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

Annotation of /trunk/Src/wptW32API.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 328 - (hide annotations)
Fri Sep 25 16:07:38 2009 UTC (15 years, 5 months ago) by twoaday
File size: 17422 byte(s)


1 werner 36 /* wptW32API.cpp - Common W32 API functions
2 twoaday 328 * Copyright (C) 2001-2003, 2005-2006, 2009 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     #ifdef HAVE_CONFIG_H
17     #include <config.h>
18     #endif
19    
20     #include <windows.h>
21     #include <stdio.h>
22     #include <sys/types.h>
23     #include <sys/stat.h>
24     #include <shellapi.h>
25     #include <shlobj.h>
26     #include <commctrl.h>
27 twoaday 129 #include <time.h>
28 werner 36
29     #include "wptNLS.h"
30     #include "wptW32API.h"
31     #include "wptErrors.h"
32     #include "wptVersion.h"
33 twoaday 204 #include "wptUTF8.h"
34 werner 36 #include "wptTypes.h"
35 twoaday 328 #include "StringBuffer.h"
36 werner 36
37    
38     extern "C" void _SHFree (void *p);
39    
40    
41 twoaday 193 /* Insert a new item into the menu @hm at position @pos. */
42     void
43     insert_menu_item (HMENU hm, int pos, UINT m_id, const char *text)
44     {
45     MENUITEMINFO mi;
46    
47     memset (&mi, 0, sizeof mi);
48     mi.cbSize = sizeof mi;
49     mi.fType = MF_STRING;
50     mi.dwTypeData = (char *)text;
51     mi.cch = strlen (text);
52     mi.wID = m_id;
53     mi.fMask = MIIM_ID|MIIM_DATA| MIIM_TYPE;
54     InsertMenuItem (hm, pos, FALSE, &mi);
55     }
56    
57    
58 werner 36 static void
59     set_menu_text_ext (HMENU menu, int by_pos, int m_uid, const char *text)
60     {
61     MENUITEMINFO mii;
62    
63     memset (&mii, 0, sizeof mii);
64     mii.cbSize = sizeof mii;
65     mii.fMask = MIIM_TYPE;
66     mii.fType = MFT_STRING;
67     mii.dwTypeData = (char *) text;
68     SetMenuItemInfo (menu, m_uid, by_pos? TRUE : FALSE, &mii);
69     }
70    
71    
72     /* Set the text of a menu item @m_uid to @text. */
73     void
74 twoaday 129 set_menu_text (HMENU menu, UINT m_uid, const char *text)
75 werner 36 {
76     set_menu_text_ext (menu, 0, m_uid, text);
77     }
78    
79    
80     /* Set the text of a menu item with the position @pos to @text. */
81     void
82 twoaday 129 set_menu_text_bypos (HMENU menu, UINT pos, const char *text)
83 werner 36 {
84     set_menu_text_ext (menu, 1, pos, text);
85     }
86    
87    
88     /* Set the state of a menu item @m_uid to @state. */
89     void
90 twoaday 129 set_menu_state (HMENU menu, UINT m_uid, UINT state)
91 werner 36 {
92     MENUITEMINFO mii;
93    
94 twoaday 121 memset (&mii, 0, sizeof (mii));
95 werner 36 mii.cbSize = sizeof (mii);
96     mii.fMask = MIIM_STATE;
97     mii.fState = state;
98     SetMenuItemInfo (menu, m_uid, FALSE, &mii);
99     }
100    
101    
102 twoaday 129 /* Retrieve the state of the menu item @m_uid and return it. */
103     UINT
104     get_menu_state (HMENU menu, UINT m_uid)
105     {
106     MENUITEMINFO mii;
107    
108     memset (&mii, 0, sizeof (mii));
109     mii.cbSize = sizeof (mii);
110     mii.fMask = MIIM_STATE;
111     GetMenuItemInfo (menu, m_uid, FALSE, &mii);
112     return mii.fState;
113     }
114    
115    
116 twoaday 77 enum {
117     CDLG_FILE_OPEN = 0,
118     CDLG_FILE_SAVE = 1
119     };
120 werner 36
121     /* Use the common dialog to request a file from the user.
122     id can be either FILE_OPEN or FILE_SAVE.
123     The return value is the file name or NULL if cancel was chosen. */
124     const char *
125 twoaday 193 get_filename_dlg (HWND hwnd, int id, const char *title,
126     const char *filter, const char *name)
127 werner 36 {
128 twoaday 271 static char file[2*MAX_PATH+1] = "";
129 twoaday 328 char _filter[512];
130 twoaday 271 char workdir[MAX_PATH+1];
131     char *sel_file = NULL;
132 werner 36 OPENFILENAME open;
133    
134 twoaday 271 if (name && strlen (name) < (DIM (file)-1))
135 werner 36 strcpy (file, name);
136     else
137     memset (file, 0, sizeof (file));
138 twoaday 328 if (!filter) {
139     strcpy (_filter, _("All Files (*.*)"));
140     memcpy (_filter+strlen (_filter)+1, "*.*\0\0", 5);
141     filter = _filter;
142     }
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 twoaday 328 static char folder[2*MAX_PATH+1] = "";
188 werner 36 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 328 /* Generates a file name from a special dirctory. */
342 twoaday 150 char*
343     make_special_filename (int folder, const char *file, const char *ext)
344     {
345     BOOL ec;
346 twoaday 328 char path[MAX_PATH+1], *p;
347 twoaday 150 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 twoaday 328 VerQueryValue (buf, (char*)"\\", &data, &qlen);
521 twoaday 121 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 twoaday 278 locale user settings. */
543 twoaday 129 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 278 ptm = localtime (&tm_t);
550     memset (&st, 0, sizeof (st));
551     st.wYear = (WORD)ptm->tm_year+1900;
552     st.wMonth = (WORD)ptm->tm_mon+1;
553 twoaday 129 st.wDay = (WORD)ptm->tm_mday;
554     if (!GetDateFormat (LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st,
555     NULL, buf, buflen))
556     return NULL;
557     return buf;
558     }
559 twoaday 121
560 twoaday 278 /* Return the time in a format which complies with the locale user
561     settings. */
562     const char*
563     get_locale_time (long tm_t, char *buf, DWORD buflen)
564     {
565     SYSTEMTIME st;
566     struct tm *ptm;
567 twoaday 121
568 twoaday 278 ptm = localtime (&tm_t);
569     memset (&st, 0, sizeof (st));
570     st.wMinute = (WORD)ptm->tm_min;
571     st.wHour = (WORD)ptm->tm_hour;
572     st.wSecond = (WORD)ptm->tm_sec;
573    
574     if (!GetTimeFormat (LOCALE_USER_DEFAULT, TIME_FORCE24HOURFORMAT, &st,
575     NULL, buf, buflen))
576     return NULL;
577     return buf;
578     }
579    
580    
581     /* Return a combination of date+time which complies to the
582     local user settings. */
583     const char*
584     get_locale_timedate (long tm_t, char *buf, DWORD buflen)
585     {
586     DWORD nleft = buflen;
587    
588     if (!get_locale_date (tm_t, buf, buflen))
589     return NULL;
590     nleft -= strlen (buf)+1;
591     if (nleft < 1)
592     return NULL;
593     strcat (buf, " ");
594     nleft--;
595     if (!get_locale_time (tm_t, buf+strlen (buf), nleft))
596     return NULL;
597     return buf;
598     }
599    
600    
601 twoaday 175 /* Generate a temporary file name by using the users
602     temp path and optionally a name @name provided by the caller.
603     Return value: 0 on success. */
604     int
605     get_temp_name (char *buf, DWORD buflen, const char *name)
606     {
607     char tmp[32];
608    
609 twoaday 271
610 twoaday 175 if (!name) {
611 twoaday 271 _snprintf (tmp, DIM (tmp)-1, "%08lX", GetTickCount ());
612 twoaday 175 name = tmp;
613     }
614 twoaday 190
615 twoaday 175 if (!GetTempPath (buflen - strlen (name) -2, buf)) {
616     log_debug ("GetTempPath() failed ec=%d\n", (int)GetLastError ());
617     return -1;
618     }
619 twoaday 271
620 twoaday 175 strcat (buf, name);
621     return 0;
622     }
623    
624    
625 twoaday 204 void
626     ListBox_AddString_utf8 (HWND lb, const char *txt)
627     {
628     char *utf8_txt;
629    
630     utf8_txt = utf8_to_native (txt);
631     SendMessage (lb, LB_ADDSTRING, 0, (LPARAM)(LPCSTR)(utf8_txt));
632     safe_free (utf8_txt);
633     }
634    
635    
636     void
637     ComboBox_AddString_utf8 (HWND cb, const char *txt)
638     {
639     char *utf8_txt;
640    
641     utf8_txt = utf8_to_native (txt);
642     SendMessage ((cb), CB_ADDSTRING, 0, (LPARAM)(LPCSTR)(utf8_txt));
643     safe_free (utf8_txt);
644     }
645    
646    
647     /* GetDlgItemText replacement with UTF8 support. */
648     int
649     GetDlgItemText_utf8 (HWND dlg, int id, char **r_txt)
650     {
651     int len = GetWindowTextLength (GetDlgItem (dlg, id));
652     char *txt;
653    
654     *r_txt = NULL;
655     if (len < 1)
656     return 0;
657     txt = new char[len+2];
658     if (!txt)
659     BUG (NULL);
660     GetDlgItemText (dlg, id, txt, len+1);
661     *r_txt = native_to_utf8 (txt);
662     free_if_alloc (txt);
663     return len;
664     }
665    
666 twoaday 328 int
667     html_help_show (int map_id)
668     {
669     STARTUPINFO si;
670     PROCESS_INFORMATION pi;
671     SECURITY_ATTRIBUTES sec_attr;
672     char path[2*MAX_PATH+1];
673    
674     memset (&sec_attr, 0, sizeof (sec_attr));
675     memset (&si, 0, sizeof (si));
676     si.cb = sizeof (STARTUPINFO);
677     memset (&pi, 0, sizeof (pi));
678     //hh.exe -mapid 40 "winpt.$lang.chm"
679    
680     _snprintf (path, 2*MAX_PATH, "hh.exe -mapid %d winpt.%s.chm",
681     map_id, gettext_get_langid ());
682     CreateProcess (NULL, path, &sec_attr, &sec_attr,
683     FALSE, 0, NULL, NULL, &si, &pi);
684     CloseHandle (pi.hProcess);
685     CloseHandle (pi.hThread);
686     return 0;
687     }
688    
689    
690 twoaday 208 /* Return TRUE if the current user has admin privileges. */
691     BOOL
692     user_is_admin (void)
693     {
694     SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY;
695 twoaday 129 HANDLE hd;
696 twoaday 208 TOKEN_GROUPS *ptg = NULL;
697     DWORD ngtoken;
698     DWORD i;
699     BOOL admin = FALSE;
700     PSID psid = 0;
701 twoaday 121
702 twoaday 208 if (GetVersion () & 0x80000000) /* Win9X */
703     return TRUE;
704 twoaday 121
705 twoaday 208 if (!OpenThreadToken (GetCurrentThread (), TOKEN_QUERY, FALSE, &hd) &&
706     !OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &hd))
707     return FALSE;
708    
709     if (!GetTokenInformation (hd, TokenGroups, NULL, 0, &ngtoken) &&
710     GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
711     ptg = (TOKEN_GROUPS*)GlobalAlloc (GPTR, ngtoken);
712     if (!ptg)
713     return FALSE;
714 twoaday 121
715 twoaday 208 if (!GetTokenInformation (hd, TokenGroups,
716     ptg, ngtoken, &ngtoken)) {
717     GlobalFree (ptg);
718     return FALSE;
719     }
720     AllocateAndInitializeSid (&SystemSidAuthority,
721     2, SECURITY_BUILTIN_DOMAIN_RID,
722     DOMAIN_ALIAS_RID_ADMINS,
723     0, 0, 0, 0, 0, 0,
724     &psid);
725     for (i = 0; i < ptg->GroupCount; i++) {
726     if (EqualSid (ptg->Groups[i].Sid, psid)) {
727     admin = TRUE;
728     break;
729     }
730     }
731     FreeSid (psid);
732     GlobalFree (ptg);
733     }
734 twoaday 121
735 twoaday 208 CloseHandle (hd);
736     return admin;
737 twoaday 129 }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26