/[winpt]/trunk/Src/wptW32API.cpp
ViewVC logotype

Annotation of /trunk/Src/wptW32API.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 271 - (hide annotations)
Sun Nov 5 08:57:45 2006 UTC (18 years, 3 months ago) by twoaday
File size: 16206 byte(s)


1 werner 36 /* wptW32API.cpp - Common W32 API functions
2 twoaday 271 * Copyright (C) 2001, 2002, 2003, 2005, 2006 Timo Schulz
3 werner 36 *
4     * This file is part of WinPT.
5     *
6     * WinPT is free software; you can redistribute it and/or modify
7     * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation; either version 2 of the License, or
9     * (at your option) any later version.
10     *
11     * WinPT is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with WinPT; if not, write to the Free Software Foundation,
18     * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19     */
20 twoaday 121
21 werner 36 #ifdef HAVE_CONFIG_H
22     #include <config.h>
23     #endif
24    
25     #include <windows.h>
26     #include <stdio.h>
27     #include <sys/types.h>
28     #include <sys/stat.h>
29     #include <shellapi.h>
30     #include <shlobj.h>
31     #include <commctrl.h>
32 twoaday 129 #include <time.h>
33 werner 36
34     #include "wptNLS.h"
35     #include "wptW32API.h"
36     #include "wptErrors.h"
37     #include "wptVersion.h"
38 twoaday 204 #include "wptUTF8.h"
39 werner 36 #include "wptTypes.h"
40    
41    
42     extern "C" void _SHFree (void *p);
43    
44    
45 twoaday 193 /* Insert a new item into the menu @hm at position @pos. */
46     void
47     insert_menu_item (HMENU hm, int pos, UINT m_id, const char *text)
48     {
49     MENUITEMINFO mi;
50    
51     memset (&mi, 0, sizeof mi);
52     mi.cbSize = sizeof mi;
53     mi.fType = MF_STRING;
54     mi.dwTypeData = (char *)text;
55     mi.cch = strlen (text);
56     mi.wID = m_id;
57     mi.fMask = MIIM_ID|MIIM_DATA| MIIM_TYPE;
58     InsertMenuItem (hm, pos, FALSE, &mi);
59     }
60    
61    
62 werner 36 static void
63     set_menu_text_ext (HMENU menu, int by_pos, int m_uid, const char *text)
64     {
65     MENUITEMINFO mii;
66    
67     memset (&mii, 0, sizeof mii);
68     mii.cbSize = sizeof mii;
69     mii.fMask = MIIM_TYPE;
70     mii.fType = MFT_STRING;
71     mii.dwTypeData = (char *) text;
72     SetMenuItemInfo (menu, m_uid, by_pos? TRUE : FALSE, &mii);
73     }
74    
75    
76     /* Set the text of a menu item @m_uid to @text. */
77     void
78 twoaday 129 set_menu_text (HMENU menu, UINT m_uid, const char *text)
79 werner 36 {
80     set_menu_text_ext (menu, 0, m_uid, text);
81     }
82    
83    
84     /* Set the text of a menu item with the position @pos to @text. */
85     void
86 twoaday 129 set_menu_text_bypos (HMENU menu, UINT pos, const char *text)
87 werner 36 {
88     set_menu_text_ext (menu, 1, pos, text);
89     }
90    
91    
92     /* Set the state of a menu item @m_uid to @state. */
93     void
94 twoaday 129 set_menu_state (HMENU menu, UINT m_uid, UINT state)
95 werner 36 {
96     MENUITEMINFO mii;
97    
98 twoaday 121 memset (&mii, 0, sizeof (mii));
99 werner 36 mii.cbSize = sizeof (mii);
100     mii.fMask = MIIM_STATE;
101     mii.fState = state;
102     SetMenuItemInfo (menu, m_uid, FALSE, &mii);
103     }
104    
105    
106 twoaday 129 /* Retrieve the state of the menu item @m_uid and return it. */
107     UINT
108     get_menu_state (HMENU menu, UINT m_uid)
109     {
110     MENUITEMINFO mii;
111    
112     memset (&mii, 0, sizeof (mii));
113     mii.cbSize = sizeof (mii);
114     mii.fMask = MIIM_STATE;
115     GetMenuItemInfo (menu, m_uid, FALSE, &mii);
116     return mii.fState;
117     }
118    
119    
120 twoaday 77 enum {
121     CDLG_FILE_OPEN = 0,
122     CDLG_FILE_SAVE = 1
123     };
124 werner 36
125     /* Use the common dialog to request a file from the user.
126     id can be either FILE_OPEN or FILE_SAVE.
127     The return value is the file name or NULL if cancel was chosen. */
128     const char *
129 twoaday 193 get_filename_dlg (HWND hwnd, int id, const char *title,
130     const char *filter, const char *name)
131 werner 36 {
132 twoaday 271 static char file[2*MAX_PATH+1] = "";
133     char workdir[MAX_PATH+1];
134     char *sel_file = NULL;
135 werner 36 OPENFILENAME open;
136    
137 twoaday 271 if (name && strlen (name) < (DIM (file)-1))
138 werner 36 strcpy (file, name);
139     else
140     memset (file, 0, sizeof (file));
141     if (!filter)
142 twoaday 167 filter = "All Files (*.*)\0*.*\0\0";
143 twoaday 271
144     GetCurrentDirectory (MAX_PATH, workdir);
145 werner 36 memset (&open, 0, sizeof (open));
146     open.lStructSize = sizeof (OPENFILENAME);
147     open.hInstance = glob_hinst;
148     open.lpstrTitle = title;
149     open.lpstrFilter = filter;
150     open.hwndOwner = hwnd;
151     open.lpstrFile = file;
152 twoaday 271 open.nMaxFile = DIM (file) - 1;
153 twoaday 77 if (id == CDLG_FILE_OPEN)
154 werner 36 open.Flags = OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST;
155     else
156     open.Flags = OFN_OVERWRITEPROMPT;
157    
158 twoaday 77 if (id == CDLG_FILE_OPEN && GetOpenFileName (&open))
159 twoaday 271 sel_file = open.lpstrFile;
160 twoaday 77 else if (id == CDLG_FILE_SAVE && GetSaveFileName (&open))
161 twoaday 271 sel_file = open.lpstrFile;
162     SetCurrentDirectory (workdir);
163 werner 36
164 twoaday 271 return sel_file;
165 werner 36 }
166    
167     const char*
168     get_filesave_dlg (HWND hwnd, const char *title,
169     const char *filter, const char *name)
170     {
171 twoaday 77 return get_filename_dlg (hwnd, CDLG_FILE_SAVE, title, filter, name);
172 werner 36 }
173    
174 twoaday 121 const char*
175 werner 36 get_fileopen_dlg (HWND hwnd, const char *title, const char *filter,
176     const char *name)
177     {
178 twoaday 77 return get_filename_dlg (hwnd, CDLG_FILE_OPEN, title, filter, name);
179 werner 36 }
180    
181    
182     /* Use the common dialog to allow the user to select a folder.
183     The return value is either the folder path or NULL if cancel was chosen. */
184     const char*
185 twoaday 121 get_folder_dlg (HWND hwnd, const char *title, const char *name)
186 werner 36 {
187     static char folder[MAX_PATH+1] = "";
188     BROWSEINFO bi;
189 twoaday 121 ITEMIDLIST *il;
190 werner 36
191     memset (&bi, 0, sizeof (bi));
192     bi.hwndOwner = hwnd;
193     if (title)
194     bi.lpszTitle = title;
195     if (name && strlen (name) < MAX_PATH-1)
196     strcpy (folder, name);
197     else
198     memset (folder, 0, sizeof (folder));
199     il = SHBrowseForFolder (&bi);
200 twoaday 271 if (il != NULL) {
201 werner 36 SHGetPathFromIDList (il, folder);
202     _SHFree (il);
203     return folder;
204     }
205     return NULL;
206     }
207    
208    
209     /* Return the clipboard contents as a string or NULL
210     if the clipboard does not contain text. */
211     char*
212     get_clip_text (HWND hwnd)
213     {
214     HANDLE clipmem;
215     char *cliptxt, *p;
216     int len;
217    
218     if (OpenClipboard (hwnd) == FALSE)
219     return NULL;
220     clipmem = GetClipboardData (CF_TEXT);
221     if (clipmem == NULL) {
222     p = NULL;
223     goto leave;
224     }
225     cliptxt = (char *) GlobalLock (clipmem);
226     if (cliptxt == NULL) {
227     p = NULL;
228     goto leave;
229     }
230    
231     len = strlen (cliptxt);
232     p = new char[len + 1];
233     if (!p)
234     BUG (NULL);
235     memcpy (p, cliptxt, len);
236     p[len] = '\0';
237     GlobalUnlock (clipmem);
238    
239     leave:
240     CloseClipboard ();
241     return p;
242     }
243    
244    
245     /* Set @text as the new clipboard content. */
246     int
247     set_clip_text (HWND hwnd, const char *text, int nbytes)
248     {
249     HANDLE clipmem;
250     int rc = 0;
251     char *p;
252    
253     if (OpenClipboard (hwnd) == FALSE)
254     return WPTERR_CLIP_OPEN;
255     EmptyClipboard ();
256    
257     clipmem = GlobalAlloc (GHND, nbytes + 1);
258     if (clipmem == NULL)
259     BUG (NULL);
260     p = (char *) GlobalLock (clipmem);
261     if (p == NULL) {
262 twoaday 196 CloseClipboard ();
263     GlobalFree (clipmem);
264     return WPTERR_GENERAL;
265 werner 36 }
266     memcpy (p, text, nbytes);
267     p[nbytes] = '\0';
268    
269 twoaday 196 SetClipboardData (CF_TEXT, clipmem);
270 werner 36 GlobalUnlock (clipmem);
271 twoaday 196 CloseClipboard ();
272 twoaday 181 GlobalFree (clipmem);
273 werner 36
274     return rc;
275 twoaday 181 }
276 werner 36
277    
278     /* Append or prepend some text to the clipboard contents.
279     If as_footer = 1, append the text otherwise prepend. */
280     int
281     set_clip_text2 (HWND hwnd, const char *text, int nbytes, int as_footer)
282     {
283 twoaday 271 const char *fmt;
284 werner 36 char *p, *new_text;
285    
286     p = get_clip_text (hwnd);
287     if (!p)
288     return WPTERR_CLIP_GET;
289 twoaday 271 if (as_footer == 0)
290     fmt = "%s\r\n%s\r\n\r\n";
291     else
292     fmt = "%s\n%s\n\n";
293     new_text = new char [strlen (p)+strlen (text)+strlen (fmt)+2];
294 werner 36 if (!new_text)
295     BUG (0);
296     if (as_footer == 0)
297 twoaday 271 sprintf (new_text, fmt, text, p);
298 werner 36 else
299 twoaday 271 sprintf (new_text, fmt, p, text);
300 werner 36 set_clip_text (hwnd, new_text, strlen (new_text)+1);
301     free_if_alloc (p);
302     free_if_alloc (new_text);
303     return 0;
304     }
305    
306    
307 twoaday 121 /* Make a file name out of the path @path, the file @file and
308     an extension. @ext.
309     Return value: the full file name on success. */
310 werner 36 char*
311     make_filename (const char *path, const char *file, const char *ext)
312     {
313     char *p;
314     size_t size = 0;
315    
316 twoaday 255 if (path && *path)
317     size += strlen (path);
318     if (file && *file)
319     size += strlen (file);
320 twoaday 271 if (ext && *ext)
321     size += strlen (ext);
322 werner 36 p = new char[size + 4];
323 twoaday 255 if (!p)
324     BUG (0);
325 twoaday 271 memset (p, 0, size);
326     if (path) {
327     strcat (p, path);
328     if (path[strlen (path) -1] != '\\')
329     strcat (p, "\\");
330 werner 36 }
331 twoaday 271 if (file != NULL)
332     strcat (p, file);
333     if (ext != NULL) {
334     strcat (p, ".");
335     strcat (p, ext);
336 werner 36 }
337     return p;
338 twoaday 121 }
339 werner 36
340    
341 twoaday 150 /* Generate a file name from a special dirctory. */
342     char*
343     make_special_filename (int folder, const char *file, const char *ext)
344     {
345     BOOL ec;
346     char path[MAX_PATH], *p;
347     size_t n=0;
348    
349     /* MSDN: buf must be at least MAX_PATH=256 bytes */
350     ec = SHGetSpecialFolderPath (HWND_DESKTOP, path, folder, TRUE);
351     if (ec != 1) {
352     log_debug ("SHGetSpecialFolderPath() failed\r\n", (int)GetLastError ());
353     return NULL;
354     }
355    
356     n = strlen (path)+1;
357     if (file)
358     n += strlen (file)+1;
359     if (ext)
360     n += strlen (ext)+1;
361     p = new char[n+2];
362     if (!p)
363     BUG (0);
364     memset (p, 0, n+2);
365     strcpy (p, path);
366     if (file) {
367     strcat (p, "\\");
368     strcat (p, file);
369     }
370     if (ext)
371     strcat (p, ext);
372     return p;
373     }
374    
375    
376 twoaday 121 /* return 0 if the file @fname exists, otherwise >0. */
377 werner 36 int
378 twoaday 121 file_exist_check (const char *fname)
379 werner 36 {
380     struct stat st;
381     if (stat (fname, &st) == -1)
382     return WPTERR_FILE_EXIST;
383     return 0;
384     }
385    
386    
387     /* Check if the current folder exists.
388     Return 0 for success. */
389     int
390     dir_exist_check (const char *dir)
391     {
392     struct stat statbuf;
393    
394 twoaday 105 if (stat (dir, &statbuf) == -1)
395 werner 36 return WPTERR_GENERAL;
396 twoaday 105 if (statbuf.st_mode & _S_IFDIR)
397 werner 36 return 0;
398     return WPTERR_GENERAL;
399     }
400    
401    
402 twoaday 77 /* Return the file size of the given file @fname. */
403     DWORD
404 werner 36 get_file_size (const char *fname)
405     {
406 twoaday 77 DWORD fsize;
407 werner 36 HANDLE fh;
408    
409 twoaday 77 fh = CreateFile (fname, GENERIC_READ, FILE_SHARE_READ,
410     NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
411     if (fh == INVALID_HANDLE_VALUE)
412 werner 36 return 0;
413 twoaday 77 fsize = GetFileSize (fh, NULL);
414     if (fsize == 0xFFFFFFFF)
415 werner 36 fsize = 0;
416 twoaday 77 CloseHandle (fh);
417 werner 36 return fsize;
418 twoaday 77 }
419 werner 36
420    
421     /* Start a dialog with the exception that before it is checked that the
422     dialog is not already openened. */
423     int
424 twoaday 105 dialog_box_param (HINSTANCE hinst, LPCTSTR name, HWND parent, DLGPROC fnc,
425     LPARAM param, LPCTSTR title, int title_id)
426 werner 36 {
427 twoaday 105 if (FindWindowEx (GetDesktopWindow (), NULL, NULL, title))
428 werner 36 return -1;
429 twoaday 105 return DialogBoxParam (hinst, name, parent, fnc, param);
430     }
431 werner 36
432    
433     /* Wrapper for message box which forces the message box into the
434     foreground and it is displayed always on top. */
435     int
436     msg_box (HWND hwnd, const char *text, const char *title, int mode)
437     {
438     mode |= MB_SETFOREGROUND;
439     mode |= MB_TASKMODAL;
440     mode |= MB_TOPMOST;
441     return MessageBox(hwnd, text, title, mode);
442     }
443    
444    
445     /* Center the hwndChild relative to parent.
446     The style param allows to specificy additional styles (like topmost). */
447     void
448     center_window2 (HWND hwndChild, HWND parent, HWND style)
449     {
450     HWND hwndParent;
451     RECT rChild, rParent;
452     HDC hdc;
453     int wChild, hChild, wParent, hParent;
454     int wScreen, hScreen, xNew, yNew;
455     int flags = SWP_NOSIZE | SWP_NOZORDER;
456    
457     hwndParent = parent;
458     if (hwndParent == NULL)
459     hwndParent = GetDesktopWindow ();
460     GetWindowRect (hwndChild, &rChild);
461     wChild = rChild.right - rChild.left;
462     hChild = rChild.bottom - rChild.top;
463    
464     GetWindowRect (hwndParent, &rParent);
465     wParent = rParent.right - rParent.left;
466     hParent = rParent.bottom - rParent.top;
467    
468     hdc = GetDC (hwndChild);
469     wScreen = GetDeviceCaps (hdc, HORZRES);
470     hScreen = GetDeviceCaps (hdc, VERTRES);
471     ReleaseDC (hwndChild, hdc);
472     xNew = rParent.left + ((wParent - wChild) /2);
473     if (xNew < 0)
474     xNew = 0;
475     else if ((xNew+wChild) > wScreen)
476     xNew = wScreen - wChild;
477     yNew = rParent.top + ((hParent - hChild) /2);
478     if (yNew < 0)
479     yNew = 0;
480     else if ((yNew+hChild) > hScreen)
481     yNew = hScreen - hChild;
482     if (style == HWND_TOPMOST || style == HWND_NOTOPMOST)
483     flags = SWP_NOMOVE | SWP_NOSIZE;
484     SetWindowPos (hwndChild, style? style : NULL, xNew, yNew, 0, 0, flags);
485     }
486    
487    
488     /* Center the given hwndChild window with no special style. */
489     void
490 twoaday 271 center_window (HWND child, HWND parent)
491 werner 36 {
492 twoaday 271 center_window2 (child, parent, NULL);
493 werner 36 }
494 twoaday 121
495    
496     /* Retrieve the product verion of the given file @fname.
497     Format: MAJOR.MINOR.PATCH1.PATCH2
498     Return value: 0 on success. */
499     int
500 twoaday 271 get_file_version (const char *fname,
501     WORD *major, WORD *minor, WORD *patch1, WORD *patch2)
502 twoaday 121 {
503 twoaday 248 VS_FIXEDFILEINFO *inf;
504 twoaday 121 char file[MAX_PATH+1] = {0};
505     LPVOID buf, data;
506     DWORD arg;
507     DWORD size;
508     UINT qlen;
509    
510     strncpy (file, fname, MAX_PATH);
511     size = GetFileVersionInfoSize (file, &arg);
512     if (!size)
513     return -1;
514 twoaday 248 buf = (LPVOID)new char[size];
515 twoaday 121 if (!buf)
516     BUG (NULL);
517     GetFileVersionInfo (file, 0, size, buf);
518    
519     qlen=0;
520     VerQueryValue (buf, "\\", &data, &qlen);
521     if (!qlen) {
522 twoaday 248 delete [](char*)buf;
523 twoaday 121 return -1;
524     }
525     inf = (VS_FIXEDFILEINFO*)data;
526    
527     if (major)
528     *major = HIWORD (inf->dwProductVersionMS);
529     if (minor)
530     *minor = LOWORD (inf->dwProductVersionMS);
531     if (patch1)
532     *patch1 = HIWORD (inf->dwProductVersionLS);
533     if (patch2)
534     *patch2 = LOWORD (inf->dwProductVersionLS);
535    
536 twoaday 248 delete [](char*)buf;
537 twoaday 121 return 0;
538     }
539    
540    
541 twoaday 129 /* Return date in a format which complies with the
542     system locale settings. */
543     const char*
544     get_locale_date (long tm_t, char *buf, DWORD buflen)
545     {
546     SYSTEMTIME st;
547     struct tm *ptm;
548 twoaday 121
549 twoaday 129 ptm = localtime (&tm_t);
550     st.wYear = (WORD)ptm->tm_year;
551     st.wMonth = (WORD)ptm->tm_mon;
552     st.wDay = (WORD)ptm->tm_mday;
553     st.wYear += 1900;
554     st.wMonth += 1;
555     if (!GetDateFormat (LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st,
556     NULL, buf, buflen))
557     return NULL;
558     return buf;
559     }
560 twoaday 121
561    
562 twoaday 175 /* Generate a temporary file name by using the users
563     temp path and optionally a name @name provided by the caller.
564     Return value: 0 on success. */
565     int
566     get_temp_name (char *buf, DWORD buflen, const char *name)
567     {
568     char tmp[32];
569    
570 twoaday 271
571 twoaday 175 if (!name) {
572 twoaday 271 _snprintf (tmp, DIM (tmp)-1, "%08lX", GetTickCount ());
573 twoaday 175 name = tmp;
574     }
575 twoaday 190
576 twoaday 271 /* In the mobile mode we need to use the current directory
577     as the temp path because no files should be stored outside
578     the USB disk drive. */
579     #ifdef WINPT_MOBILE
580     memset (buf, 0, buflen);
581     strncpy (buf, name, buflen-1);
582     return 0;
583     #endif
584 twoaday 190
585 twoaday 175 if (!GetTempPath (buflen - strlen (name) -2, buf)) {
586     log_debug ("GetTempPath() failed ec=%d\n", (int)GetLastError ());
587     return -1;
588     }
589 twoaday 271
590 twoaday 175 strcat (buf, name);
591     return 0;
592     }
593    
594    
595 twoaday 204 void
596     ListBox_AddString_utf8 (HWND lb, const char *txt)
597     {
598     char *utf8_txt;
599    
600     utf8_txt = utf8_to_native (txt);
601     SendMessage (lb, LB_ADDSTRING, 0, (LPARAM)(LPCSTR)(utf8_txt));
602     safe_free (utf8_txt);
603     }
604    
605    
606     void
607     ComboBox_AddString_utf8 (HWND cb, const char *txt)
608     {
609    
610     char *utf8_txt;
611    
612     utf8_txt = utf8_to_native (txt);
613     SendMessage ((cb), CB_ADDSTRING, 0, (LPARAM)(LPCSTR)(utf8_txt));
614     safe_free (utf8_txt);
615     }
616    
617    
618     /* GetDlgItemText replacement with UTF8 support. */
619     int
620     GetDlgItemText_utf8 (HWND dlg, int id, char **r_txt)
621     {
622     int len = GetWindowTextLength (GetDlgItem (dlg, id));
623     char *txt;
624    
625     *r_txt = NULL;
626     if (len < 1)
627     return 0;
628     txt = new char[len+2];
629     if (!txt)
630     BUG (NULL);
631     GetDlgItemText (dlg, id, txt, len+1);
632     *r_txt = native_to_utf8 (txt);
633     free_if_alloc (txt);
634     return len;
635     }
636    
637    
638 twoaday 208 /* Return TRUE if the current user has admin privileges. */
639     BOOL
640     user_is_admin (void)
641     {
642     SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY;
643 twoaday 129 HANDLE hd;
644 twoaday 208 TOKEN_GROUPS *ptg = NULL;
645     DWORD ngtoken;
646     DWORD i;
647     BOOL admin = FALSE;
648     PSID psid = 0;
649 twoaday 121
650 twoaday 208 if (GetVersion () & 0x80000000) /* Win9X */
651     return TRUE;
652 twoaday 121
653 twoaday 208 if (!OpenThreadToken (GetCurrentThread (), TOKEN_QUERY, FALSE, &hd) &&
654     !OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &hd))
655     return FALSE;
656    
657     if (!GetTokenInformation (hd, TokenGroups, NULL, 0, &ngtoken) &&
658     GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
659     ptg = (TOKEN_GROUPS*)GlobalAlloc (GPTR, ngtoken);
660     if (!ptg)
661     return FALSE;
662 twoaday 121
663 twoaday 208 if (!GetTokenInformation (hd, TokenGroups,
664     ptg, ngtoken, &ngtoken)) {
665     GlobalFree (ptg);
666     return FALSE;
667     }
668     AllocateAndInitializeSid (&SystemSidAuthority,
669     2, SECURITY_BUILTIN_DOMAIN_RID,
670     DOMAIN_ALIAS_RID_ADMINS,
671     0, 0, 0, 0, 0, 0,
672     &psid);
673     for (i = 0; i < ptg->GroupCount; i++) {
674     if (EqualSid (ptg->Groups[i].Sid, psid)) {
675     admin = TRUE;
676     break;
677     }
678     }
679     FreeSid (psid);
680     GlobalFree (ptg);
681     }
682 twoaday 121
683 twoaday 208 CloseHandle (hd);
684     return admin;
685 twoaday 129 }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26