D-Bus
1.6.8
|
00001 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 00002 /* dbus-sysdeps-wince-glue.c Wrappers for Windows CE around system/libc features (internal to D-BUS implementation) 00003 * 00004 * Copyright (C) 2002, 2003 Red Hat, Inc. 00005 * Copyright (C) 2003 CodeFactory AB 00006 * Copyright (C) 2005 Novell, Inc. 00007 * Copyright (C) 2006 Ralf Habacker <ralf.habacker@freenet.de> 00008 * Copyright (C) 2006 Peter Kümmel <syntheticpp@gmx.net> 00009 * Copyright (C) 2006 Christian Ehrlicher <ch.ehrlicher@gmx.de> 00010 * 00011 * Licensed under the Academic Free License version 2.1 00012 * 00013 * This program is free software; you can redistribute it and/or modify 00014 * it under the terms of the GNU General Public License as published by 00015 * the Free Software Foundation; either version 2 of the License, or 00016 * (at your option) any later version. 00017 * 00018 * This program is distributed in the hope that it will be useful, 00019 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00020 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00021 * GNU General Public License for more details. 00022 * 00023 * You should have received a copy of the GNU General Public License 00024 * along with this program; if not, write to the Free Software 00025 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00026 * 00027 */ 00028 00029 #include <config.h> 00030 #include "dbus-internals.h" 00031 #include "dbus-sysdeps.h" 00032 #include "dbus-sysdeps-win.h" 00033 00034 #include <windows.h> 00035 /* Including shlobj.h creates trouble on some compilers. Just chicken 00036 out here by defining just what we need. */ 00037 #ifndef CSIDL_PERSONAL 00038 #define CSIDL_PERSONAL 5 00039 #endif 00040 00041 00042 /* Copy SRC to DEST, returning the address of the terminating '\0' in DEST. */ 00043 static char * 00044 stpcpy (char *dest, const char *src) 00045 { 00046 char *d = dest; 00047 const char *s = src; 00048 00049 do 00050 *d++ = *s; 00051 while (*s++ != '\0'); 00052 00053 return d - 1; 00054 } 00055 00056 00057 /* This is special cased, because we must avoid using many dbus 00058 functions (such as memory allocations): Those functions may in turn 00059 cause verbose output and check the flag! */ 00060 static char * 00061 get_verbose_setting() 00062 { 00063 const wchar_t dir[] = L"Software\\freedesktop\\DBus"; 00064 const wchar_t name[] = L"Verbose"; 00065 HKEY root_key; 00066 HKEY key_handle; 00067 DWORD nbytes; 00068 DWORD n1; 00069 DWORD type; 00070 wchar_t *result_w = NULL; 00071 char *result; 00072 int len; 00073 00074 root_key = HKEY_LOCAL_MACHINE; 00075 if (RegOpenKeyExW (root_key, dir, 0, KEY_READ, &key_handle)) 00076 return NULL; 00077 00078 nbytes = 1; 00079 if (RegQueryValueExW (key_handle, name, 0, NULL, NULL, &nbytes)) 00080 { 00081 RegCloseKey (key_handle); 00082 return NULL; 00083 } 00084 /* Round up to multiple of wchar_t, convert to number of wchar_t's, and add 1. */ 00085 n1 = ((nbytes + sizeof(wchar_t) - 1) / sizeof (wchar_t)) + 1; 00086 result_w = malloc (n1 * sizeof (wchar_t)); 00087 if (!result_w) 00088 { 00089 RegCloseKey (key_handle); 00090 return NULL; 00091 } 00092 if (RegQueryValueExW (key_handle, name, 0, &type, (LPBYTE) result_w, &nbytes)) 00093 { 00094 RegCloseKey (key_handle); 00095 free (result_w); 00096 return NULL; 00097 } 00098 RegCloseKey (key_handle); 00099 result_w[n1 - 1] = 0; /* Make sure it is really a string. */ 00100 00101 /* NOTE: REG_MULTI_SZ and REG_EXPAND_SZ not supported, because they 00102 are not needed in this module. */ 00103 if (type != REG_SZ) 00104 { 00105 free (result_w); 00106 return NULL; 00107 } 00108 00109 len = WideCharToMultiByte (CP_UTF8, 0, result_w, -1, NULL, 0, NULL, NULL); 00110 if (len < 0) 00111 { 00112 free (result_w); 00113 return NULL; 00114 } 00115 00116 result = malloc (len + 1); 00117 if (!result) 00118 { 00119 free (result_w); 00120 return NULL; 00121 } 00122 00123 len = WideCharToMultiByte (CP_UTF8, 0, result_w, -1, result, len, NULL, NULL); 00124 free (result_w); 00125 if (len < 0) 00126 { 00127 free (result); 00128 return NULL; 00129 } 00130 return result; 00131 } 00132 00133 00134 /* Return a string from the W32 Registry or NULL in case of error. 00135 Caller must release the return value. A NULL for root is an alias 00136 for HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE in turn. */ 00137 static char * 00138 read_w32_registry_string (const char *root, const char *dir, const char *name) 00139 { 00140 HKEY root_key, key_handle; 00141 DWORD n1, nbytes, type; 00142 char *result = NULL; 00143 00144 if ( !root ) 00145 root_key = HKEY_CURRENT_USER; 00146 else if ( !strcmp( root, "HKEY_CLASSES_ROOT" ) ) 00147 root_key = HKEY_CLASSES_ROOT; 00148 else if ( !strcmp( root, "HKEY_CURRENT_USER" ) ) 00149 root_key = HKEY_CURRENT_USER; 00150 else if ( !strcmp( root, "HKEY_LOCAL_MACHINE" ) ) 00151 root_key = HKEY_LOCAL_MACHINE; 00152 else if ( !strcmp( root, "HKEY_USERS" ) ) 00153 root_key = HKEY_USERS; 00154 else 00155 return NULL; 00156 00157 if (RegOpenKeyExA (root_key, dir, 0, KEY_READ, &key_handle)) 00158 { 00159 if (root) 00160 return NULL; /* no need for a RegClose, so return direct */ 00161 /* It seems to be common practise to fall back to HKLM. */ 00162 if (RegOpenKeyExA (HKEY_LOCAL_MACHINE, dir, 0, KEY_READ, &key_handle)) 00163 return NULL; /* still no need for a RegClose, so return direct */ 00164 } 00165 00166 nbytes = 1; 00167 if (RegQueryValueExA (key_handle, name, 0, NULL, NULL, &nbytes)) 00168 { 00169 if (root) 00170 goto out; 00171 /* Try to fallback to HKLM also for a missing value. */ 00172 RegCloseKey (key_handle); 00173 if (RegOpenKeyExA (HKEY_LOCAL_MACHINE, dir, 0, KEY_READ, &key_handle)) 00174 return NULL; /* Nope. */ 00175 if (RegQueryValueExA (key_handle, name, 0, NULL, NULL, &nbytes)) 00176 goto out; 00177 } 00178 n1 = nbytes + 1; 00179 result = malloc (n1); 00180 if (!result) 00181 goto out; 00182 if (RegQueryValueExA (key_handle, name, 0, &type, result, &n1)) 00183 { 00184 free(result); 00185 result = NULL; 00186 goto out; 00187 } 00188 result[nbytes] = 0; /* Make sure it is really a string. */ 00189 00190 out: 00191 RegCloseKey (key_handle); 00192 return result; 00193 } 00194 00195 00196 static char * 00197 find_inst_dir () 00198 { 00199 return read_w32_registry_string ("HKEY_LOCAL_MACHINE", 00200 "Software\\freedesktop\\DBus", 00201 "Install Directory"); 00202 } 00203 00204 00205 static char * 00206 find_env_in_registry (const char *name) 00207 { 00208 return read_w32_registry_string ("HKEY_LOCAL_MACHINE", 00209 "Software\\freedesktop\\DBus", 00210 name); 00211 } 00212 00213 00214 static char * 00215 find_program_in_inst_dir (const char *name) 00216 { 00217 char *result = NULL; 00218 char *tmp; 00219 00220 tmp = find_inst_dir (); 00221 if (!tmp) 00222 return NULL; 00223 00224 result = malloc (strlen (tmp) + 5 + strlen (name) + 1); 00225 if (!result) 00226 { 00227 free (tmp); 00228 return NULL; 00229 } 00230 00231 strcpy (stpcpy (stpcpy (result, tmp), "\\bin\\"), name); 00232 free (tmp); 00233 00234 return result; 00235 } 00236 00237 00238 static char * 00239 find_inst_subdir (const char *name) 00240 { 00241 char *result = NULL; 00242 char *tmp; 00243 00244 tmp = find_inst_dir (); 00245 if (!tmp) 00246 return NULL; 00247 00248 result = malloc (strlen (tmp) + 1 + strlen (name) + 1); 00249 if (!result) 00250 { 00251 free (tmp); 00252 return NULL; 00253 } 00254 00255 strcpy (stpcpy (stpcpy (result, tmp), "\\"), name); 00256 free (tmp); 00257 00258 return result; 00259 } 00260 00261 00262 static char * 00263 find_my_documents_folder () 00264 { 00265 /* One for safety, just in case. */ 00266 char dir[MAX_PATH + 1]; 00267 char *result; 00268 00269 dir[0] = '\0'; 00270 /* May return false even if successful. */ 00271 SHGetSpecialFolderPathA (0, dir, CSIDL_PERSONAL, 0); 00272 if (dir[0] == '\0') 00273 return NULL; 00274 00275 result = malloc (strlen (dir) + 1); 00276 if (!result) 00277 return NULL; 00278 strcpy (result, dir); 00279 return result; 00280 } 00281 00282 00283 #define MAX_ENV 30 00284 00285 char *environ[MAX_ENV + 1]; 00286 00287 char * 00288 getenv (const char *name) 00289 { 00290 static char *past_result; 00291 char **envp; 00292 int idx; 00293 00294 if (past_result) 00295 { 00296 free (past_result); 00297 past_result = NULL; 00298 } 00299 00300 if (! strcmp (name, "DBUS_VERBOSE")) 00301 return past_result = get_verbose_setting (); 00302 else if (! strcmp (name, "HOMEPATH")) 00303 return past_result = find_my_documents_folder (); 00304 else if (! strcmp (name, "DBUS_DATADIR")) 00305 return past_result = find_inst_subdir ("share"); 00306 00307 for (envp = environ; *envp != 0; envp++) 00308 { 00309 const char *varp = name; 00310 char *ep = *envp; 00311 int same_name = 0; 00312 00313 while (*varp == *ep && *varp != '\0') 00314 { 00315 ++ep; 00316 ++varp; 00317 }; 00318 00319 if (*varp == '\0' && *ep == '=') 00320 return ep + 1; 00321 } 00322 00323 return NULL; 00324 } 00325 00326 00327 int 00328 putenv (char *str) 00329 { 00330 char **envp; 00331 int idx; 00332 for (envp = environ; *envp != 0; envp++) 00333 { 00334 char *varp = str; 00335 char *ep = *envp; 00336 int same_name = 0; 00337 00338 while (*varp == *ep && *varp != '\0') 00339 { 00340 if (*varp == '=') 00341 same_name = 1; 00342 ++ep; 00343 ++varp; 00344 }; 00345 00346 if (*varp == *ep && *varp == '\0') 00347 return 0; 00348 if (same_name) 00349 { 00350 *envp = str; 00351 return 0; 00352 } 00353 } 00354 00355 idx = envp - environ; 00356 if (idx > MAX_ENV) 00357 { 00358 _dbus_win_set_errno (ENOMEM); 00359 return -1; 00360 } 00361 00362 environ[idx] = str; 00363 return 0; 00364 } 00365 00366 00367 clock_t 00368 clock (void) 00369 { 00370 return GetTickCount (); 00371 } 00372 00373 00374 void 00375 abort (void) 00376 { 00377 /* This is what windows does. */ 00378 exit (3); 00379 } 00380 00381 00382 void 00383 GetSystemTimeAsFileTime (LPFILETIME ftp) 00384 { 00385 SYSTEMTIME st; 00386 GetSystemTime (&st); 00387 SystemTimeToFileTime (&st, ftp); 00388 } 00389 00390 00391 unsigned char* 00392 _mbsrchr (const unsigned char* str, unsigned int ch) 00393 { 00394 /* FIXME. This is not multi-byte safe. */ 00395 return strrchr (str, ch); 00396 } 00397 00398 00399 HANDLE OpenFileMappingA(DWORD dwDesiredAccess, 00400 BOOL bInheritHandle, 00401 LPCSTR lpName) 00402 { 00403 DWORD flProtect = 0; 00404 HANDLE hMapping; 00405 00406 if (dwDesiredAccess & FILE_MAP_READ) 00407 flProtect |= PAGE_READONLY; 00408 00409 if (dwDesiredAccess & FILE_MAP_WRITE) 00410 flProtect |= PAGE_READWRITE; 00411 00412 SetLastError (0); 00413 hMapping = CreateFileMappingA(INVALID_HANDLE_VALUE, 00414 NULL, flProtect, 0, 0, lpName); 00415 if (hMapping != INVALID_HANDLE_VALUE) 00416 { 00417 /* Just in case Windows CE changes its behaviour, we check for 00418 the right error value here. */ 00419 if (GetLastError () != ERROR_ALREADY_EXISTS) 00420 { 00421 CloseHandle(hMapping); 00422 hMapping = INVALID_HANDLE_VALUE; 00423 } 00424 } 00425 return hMapping; 00426 } 00427 00428 00429 BOOL 00430 MoveFileExA (LPCSTR lpExistingFileName, LPCSTR lpNewFileName, DWORD dwFlags) 00431 { 00432 _dbus_assert (dwFlags == MOVEFILE_REPLACE_EXISTING); 00433 00434 if (_dbus_file_exists (lpNewFileName)) 00435 { 00436 BOOL result = DeleteFileA (lpNewFileName); 00437 if (result == 0) 00438 return FALSE; 00439 } 00440 return MoveFileA (lpExistingFileName, lpNewFileName); 00441 } 00442 00443 00444 BOOL 00445 SetHandleInformation (HANDLE hObject, DWORD dwMask, DWORD dwFlags) 00446 { 00447 _dbus_assert (dwMask == (HANDLE_FLAG_INHERIT | HANDLE_FLAG_PROTECT_FROM_CLOSE)); 00448 _dbus_assert (dwFlags == 0); 00449 00450 /* Not supported on Windows CE, and actually the default. So just 00451 return overwhelming success. */ 00452 return 1; 00453 } 00454 00455 00456 DWORD 00457 SearchPathA (LPCSTR lpPath, LPCSTR lpFileName, LPCSTR lpExtension, 00458 DWORD nBufferLength, LPSTR lpBuffer, LPSTR* lpFilePart) 00459 { 00460 char *filename; 00461 char *filepart; 00462 int filename_len; 00463 00464 _dbus_assert (lpPath == NULL); 00465 _dbus_assert (lpExtension == NULL); 00466 00467 filename = find_program_in_inst_dir (lpFileName); 00468 if (!filename) 00469 { 00470 SetLastError (ERROR_FILE_NOT_FOUND); 00471 return 0; 00472 } 00473 00474 filename_len = strlen (filename) + 1; 00475 if (filename_len > nBufferLength) 00476 { 00477 free (filename); 00478 return filename_len; 00479 } 00480 00481 strcpy (lpBuffer, filename); 00482 free (filename); 00483 00484 filepart = _mbsrchr (lpBuffer, '\\'); 00485 if (!filepart) 00486 filepart = lpBuffer; 00487 *lpFilePart = filepart; 00488 00489 return filename_len - 1; 00490 } 00491 00492 00497 dbus_bool_t 00498 _dbus_getsid(char **sid) 00499 { 00500 /* There is nothing like this on Windows CE, so we fake it. */ 00501 static const char asid[] = "S-1-5-21-515967899-920026266-1708537768-1000"; 00502 char *buf = LocalAlloc (LMEM_FIXED, sizeof (asid)); 00503 if (!buf) 00504 { 00505 _dbus_win_warn_win_error ("LocalAlloc failed", GetLastError ()); 00506 return FALSE; 00507 } 00508 00509 memcpy (buf, asid, sizeof (asid)); 00510 *sid = buf; 00511 return TRUE; 00512 } 00513 00514 00515 BOOL 00516 LookupAccountNameW (LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid, PDWORD cbSid, 00517 LPWSTR ReferencedDomainName, PDWORD cchReferencedDomainName, PSID_NAME_USE peUse) 00518 { 00519 /* Currently not needed. */ 00520 return FALSE; 00521 } 00522 00523 00524 BOOL 00525 IsValidSid (PSID psid) 00526 { 00527 /* Currently not needed. */ 00528 return FALSE; 00529 } 00530 00531 00532 HANDLE 00533 CreateFileA (LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwSharedMode, 00534 LPSECURITY_ATTRIBUTES lpSecurityAttributes, 00535 DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, 00536 HANDLE hTemplateFile) 00537 { 00538 wchar_t *filename; 00539 HANDLE result; 00540 int err; 00541 00542 filename = _dbus_win_utf8_to_utf16 (lpFileName, NULL); 00543 if (!filename) 00544 return INVALID_HANDLE_VALUE; 00545 00546 result = CreateFileW (filename, dwDesiredAccess, dwSharedMode, 00547 lpSecurityAttributes, dwCreationDisposition, 00548 dwFlagsAndAttributes, hTemplateFile); 00549 00550 err = GetLastError (); 00551 dbus_free (filename); 00552 SetLastError (err); 00553 return result; 00554 } 00555 00556 00557 BOOL 00558 DeleteFileA (LPCSTR lpFileName) 00559 { 00560 wchar_t *filename; 00561 BOOL result; 00562 int err; 00563 00564 filename = _dbus_win_utf8_to_utf16 (lpFileName, NULL); 00565 if (!filename) 00566 return FALSE; 00567 00568 result = DeleteFileW (filename); 00569 00570 err = GetLastError (); 00571 dbus_free (filename); 00572 SetLastError (err); 00573 return result; 00574 } 00575 00576 00577 BOOL 00578 MoveFileA (LPCSTR lpExistingFileName, LPCSTR lpNewFileName) 00579 { 00580 wchar_t *existing_filename; 00581 wchar_t *new_filename; 00582 BOOL result; 00583 int err; 00584 00585 existing_filename = _dbus_win_utf8_to_utf16 (lpExistingFileName, NULL); 00586 if (! existing_filename) 00587 return FALSE; 00588 00589 new_filename = _dbus_win_utf8_to_utf16 (lpNewFileName, NULL); 00590 if (! new_filename) 00591 { 00592 dbus_free (existing_filename); 00593 return FALSE; 00594 } 00595 00596 result = MoveFileW (existing_filename, new_filename); 00597 00598 err = GetLastError (); 00599 dbus_free (existing_filename); 00600 dbus_free (new_filename); 00601 SetLastError (err); 00602 return result; 00603 } 00604 00605 00606 DWORD 00607 GetFileAttributesA(LPCSTR lpFileName) 00608 { 00609 wchar_t *filename; 00610 DWORD result; 00611 int err; 00612 00613 filename = _dbus_win_utf8_to_utf16 (lpFileName, NULL); 00614 if (!filename) 00615 return INVALID_FILE_ATTRIBUTES; 00616 00617 result = GetFileAttributesW (filename); 00618 00619 err = GetLastError (); 00620 dbus_free (filename); 00621 SetLastError (err); 00622 return result; 00623 } 00624 00625 00626 BOOL 00627 GetFileAttributesExA (LPCSTR lpFileName, GET_FILEEX_INFO_LEVELS fInfoLevelId, 00628 PVOID lpFileInformation) 00629 { 00630 wchar_t *filename; 00631 DWORD result; 00632 int err; 00633 00634 filename = _dbus_win_utf8_to_utf16 (lpFileName, NULL); 00635 if (!filename) 00636 return INVALID_FILE_ATTRIBUTES; 00637 00638 result = GetFileAttributesExW (filename, fInfoLevelId, lpFileInformation); 00639 00640 err = GetLastError (); 00641 dbus_free (filename); 00642 SetLastError (err); 00643 return result; 00644 } 00645 00646 00647 HANDLE 00648 CreateFileMappingA (HANDLE hFile, LPSECURITY_ATTRIBUTES lpAttributes, 00649 DWORD flProtect, DWORD dwMaximumSizeHigh, 00650 DWORD dwMaximumSizeLow, LPCSTR lpName) 00651 { 00652 wchar_t *name; 00653 HANDLE result; 00654 int err; 00655 00656 if (lpName) 00657 { 00658 name = _dbus_win_utf8_to_utf16 (lpName, NULL); 00659 if (!name) 00660 return INVALID_HANDLE_VALUE; 00661 } 00662 else 00663 name = NULL; 00664 00665 result = CreateFileMappingW (hFile, lpAttributes, flProtect, 00666 dwMaximumSizeHigh, dwMaximumSizeLow, 00667 name); 00668 00669 err = GetLastError (); 00670 dbus_free (name); 00671 SetLastError (err); 00672 return result; 00673 } 00674 00675 00676 BOOL 00677 CreateDirectoryA (LPCSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes) 00678 { 00679 wchar_t *pathname; 00680 BOOL result; 00681 int err; 00682 00683 pathname = _dbus_win_utf8_to_utf16 (lpPathName, NULL); 00684 if (!pathname) 00685 return FALSE; 00686 00687 result = CreateDirectoryW (pathname, lpSecurityAttributes); 00688 00689 err = GetLastError (); 00690 dbus_free (pathname); 00691 SetLastError (err); 00692 return result; 00693 } 00694 00695 00696 BOOL 00697 RemoveDirectoryA (LPCSTR lpPathName) 00698 { 00699 wchar_t *pathname; 00700 BOOL result; 00701 int err; 00702 00703 pathname = _dbus_win_utf8_to_utf16 (lpPathName, NULL); 00704 if (!pathname) 00705 return FALSE; 00706 00707 result = RemoveDirectoryW (pathname); 00708 00709 err = GetLastError (); 00710 dbus_free (pathname); 00711 SetLastError (err); 00712 return result; 00713 } 00714 00715 00716 static BOOL 00717 convert_find_data (LPWIN32_FIND_DATAW fdw, LPWIN32_FIND_DATAA fda) 00718 { 00719 char *filename; 00720 int len; 00721 00722 fda->dwFileAttributes = fdw->dwFileAttributes; 00723 fda->ftCreationTime = fdw->ftCreationTime; 00724 fda->ftLastAccessTime = fdw->ftLastAccessTime; 00725 fda->ftLastWriteTime = fdw->ftLastWriteTime; 00726 fda->nFileSizeHigh = fdw->nFileSizeHigh; 00727 fda->nFileSizeLow = fdw->nFileSizeLow; 00728 00729 filename = _dbus_win_utf16_to_utf8 (fdw->cFileName, NULL); 00730 if (!filename) 00731 return FALSE; 00732 00733 len = sizeof (fda->cFileName); 00734 strncpy (fda->cFileName, filename, len); 00735 fda->cFileName[len - 1] = '\0'; 00736 00737 return TRUE; 00738 } 00739 00740 00741 HANDLE 00742 FindFirstFileA (LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData) 00743 { 00744 wchar_t *pathname; 00745 WIN32_FIND_DATAW find_file_data; 00746 HANDLE result; 00747 int err; 00748 00749 pathname = _dbus_win_utf8_to_utf16 (lpFileName, NULL); 00750 if (!pathname) 00751 return INVALID_HANDLE_VALUE; 00752 00753 result = FindFirstFileW (pathname, &find_file_data); 00754 if (result != INVALID_HANDLE_VALUE) 00755 { 00756 BOOL res = convert_find_data (&find_file_data, lpFindFileData); 00757 if (! res) 00758 { 00759 err = GetLastError (); 00760 FindClose (result); 00761 SetLastError (err); 00762 result = INVALID_HANDLE_VALUE; 00763 } 00764 } 00765 00766 err = GetLastError (); 00767 dbus_free (pathname); 00768 SetLastError (err); 00769 return result; 00770 } 00771 00772 00773 BOOL 00774 FindNextFileA (HANDLE hFindFile, LPWIN32_FIND_DATAA lpFindFileData) 00775 { 00776 WIN32_FIND_DATAW find_file_data; 00777 BOOL result; 00778 int err; 00779 00780 result = FindNextFileW (hFindFile, &find_file_data); 00781 if (result) 00782 result = convert_find_data (&find_file_data, lpFindFileData); 00783 00784 return result; 00785 } 00786 00787 00788 HANDLE 00789 CreateMutexA (LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, 00790 LPCSTR lpName) 00791 { 00792 wchar_t *name; 00793 HANDLE result; 00794 int err; 00795 00796 if (lpName) 00797 { 00798 name = _dbus_win_utf8_to_utf16 (lpName, NULL); 00799 if (!name) 00800 return INVALID_HANDLE_VALUE; 00801 } 00802 else 00803 name = NULL; 00804 00805 result = CreateMutexW (lpMutexAttributes, bInitialOwner, name); 00806 00807 err = GetLastError (); 00808 dbus_free (name); 00809 SetLastError (err); 00810 return result; 00811 } 00812 00813 00814 BOOL 00815 CreateProcessA (LPCSTR pszImageName, LPSTR pszCmdLine, 00816 LPSECURITY_ATTRIBUTES psaProcess, 00817 LPSECURITY_ATTRIBUTES psaThread, BOOL fInheritHandles, 00818 DWORD fdwCreate, PVOID pvEnvironment, LPCSTR pszCurDir, 00819 LPSTARTUPINFOA psiStartInfo, 00820 LPPROCESS_INFORMATION pProcInfo) 00821 { 00822 wchar_t *image_name = NULL; 00823 wchar_t *cmd_line = NULL; 00824 BOOL result; 00825 int err; 00826 00827 _dbus_assert (psaProcess == NULL); 00828 _dbus_assert (psaThread == NULL); 00829 _dbus_assert (fInheritHandles == FALSE); 00830 _dbus_assert (pvEnvironment == NULL); 00831 _dbus_assert (pszCurDir == NULL); 00832 /* psiStartInfo is generally not NULL. */ 00833 00834 if (pszImageName) 00835 { 00836 image_name = _dbus_win_utf8_to_utf16 (pszImageName, NULL); 00837 if (!image_name) 00838 return 0; 00839 } 00840 if (pszCmdLine) 00841 { 00842 cmd_line = _dbus_win_utf8_to_utf16 (pszCmdLine, NULL); 00843 if (!cmd_line) 00844 { 00845 if (image_name) 00846 dbus_free (image_name); 00847 return 0; 00848 } 00849 } 00850 00851 result = CreateProcessW (image_name, cmd_line, NULL, NULL, FALSE, 00852 fdwCreate, NULL, NULL, NULL, pProcInfo); 00853 00854 err = GetLastError (); 00855 dbus_free (image_name); 00856 dbus_free (cmd_line); 00857 SetLastError (err); 00858 return result; 00859 } 00860 00861 00862 LONG 00863 RegOpenKeyExA (HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, 00864 REGSAM samDesired, PHKEY phkResult) 00865 { 00866 wchar_t *subkey; 00867 LONG result; 00868 int err; 00869 00870 if (lpSubKey) 00871 { 00872 subkey = _dbus_win_utf8_to_utf16 (lpSubKey, NULL); 00873 if (!subkey) 00874 return 0; 00875 } 00876 else 00877 subkey = NULL; 00878 00879 result = RegOpenKeyEx (hKey, subkey, ulOptions, samDesired, phkResult); 00880 00881 err = GetLastError (); 00882 dbus_free (subkey); 00883 SetLastError (err); 00884 return result; 00885 } 00886 00887 00888 LONG 00889 RegQueryValueExA (HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved, 00890 LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData) 00891 { 00892 wchar_t *name; 00893 LONG err; 00894 BYTE *data; 00895 DWORD data_len; 00896 DWORD type; 00897 00898 if (lpValueName) 00899 { 00900 name = _dbus_win_utf8_to_utf16 (lpValueName, NULL); 00901 if (!name) 00902 return GetLastError (); 00903 } 00904 else 00905 name = NULL; 00906 00907 data_len = 0; 00908 err = RegQueryValueExW (hKey, name, lpReserved, lpType, NULL, &data_len); 00909 if (err || !lpcbData) 00910 { 00911 dbus_free (name); 00912 return err; 00913 } 00914 00915 data = malloc (data_len + sizeof (wchar_t)); 00916 if (!data) 00917 { 00918 dbus_free (name); 00919 return ERROR_NOT_ENOUGH_MEMORY; 00920 } 00921 00922 err = RegQueryValueExW (hKey, name, lpReserved, &type, data, &data_len); 00923 if (lpType) 00924 *lpType = type; 00925 dbus_free (name); 00926 /* If err is ERROR_MORE_DATA, there probably was a race condition. 00927 We can punt this to the caller just as well. */ 00928 if (err) 00929 { 00930 free (data); 00931 return err; 00932 } 00933 00934 /* NOTE: REG_MULTI_SZ and REG_EXPAND_SZ not supported, because they 00935 are not needed in this module. */ 00936 if (type == REG_SZ) 00937 { 00938 char *data_c; 00939 int data_c_len; 00940 00941 /* This is valid since we allocated one more above. */ 00942 data[data_len] = '\0'; 00943 data[data_len + 1] = '\0'; 00944 00945 /* The cast is valid because malloc guarantees alignment of 00946 basic types. */ 00947 data_c = _dbus_win_utf16_to_utf8 ((wchar_t*) data, NULL); 00948 if (!data_c) 00949 { 00950 free (data); 00951 return GetLastError(); 00952 } 00953 00954 data_c_len = strlen (data_c) + 1; 00955 _dbus_assert (data_c_len <= data_len + sizeof (wchar_t)); 00956 memcpy (data, data_c, data_c_len); 00957 data_len = data_c_len; 00958 dbus_free (data_c); 00959 } 00960 00961 /* DATA and DATA_LEN now contain the result. */ 00962 if (lpData) 00963 { 00964 if (data_len > *lpcbData) 00965 err = ERROR_MORE_DATA; 00966 else 00967 memcpy (lpData, data, data_len); 00968 } 00969 free (data); 00970 *lpcbData = data_len; 00971 return err; 00972 } 00973 00974 00975 DWORD 00976 FormatMessageA (DWORD dwFlags, PCVOID lpSource, DWORD dwMessageId, 00977 DWORD dwLanguageId, LPSTR lpBuffer, DWORD nSize, 00978 va_list* Arguments) 00979 { 00980 LPWSTR buffer_w = NULL; 00981 LPSTR buffer_c; 00982 DWORD len; 00983 char *buffer_new; 00984 DWORD buffer_new_len; 00985 BOOL buffer_w_free; 00986 00987 len = FormatMessageW (dwFlags | FORMAT_MESSAGE_ALLOCATE_BUFFER, 00988 lpSource, dwMessageId, dwLanguageId, 00989 (LPWSTR) &buffer_w, 0, Arguments); 00990 if (len == 0) 00991 return 0; 00992 00993 buffer_c = _dbus_win_utf16_to_utf8 (buffer_w, NULL); 00994 if (! buffer_c) 00995 { 00996 LocalFree (buffer_w); 00997 return 0; 00998 } 00999 01000 if (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) 01001 { 01002 /* We need to return a buffer that's freeable with LocalFree. */ 01003 buffer_new = (char *) buffer_w; 01004 buffer_new_len = sizeof (wchar_t) * (len + 1); 01005 buffer_w_free = FALSE; 01006 /* Avoid alignment issue by using memcpy. */ 01007 memcpy (lpBuffer, &buffer_new, sizeof (buffer_new)); 01008 } 01009 else 01010 { 01011 buffer_new = lpBuffer; 01012 buffer_new_len = nSize; 01013 buffer_w_free = TRUE; 01014 } 01015 01016 strncpy (buffer_new, buffer_c, buffer_new_len); 01017 dbus_free (buffer_c); 01018 buffer_new[buffer_new_len - 1] = '\0'; 01019 if (buffer_w_free) 01020 LocalFree (buffer_w); 01021 01022 /* strlen is correct (not _mbstrlen), because we want storage and 01023 not string length. */ 01024 return strlen (buffer_new); 01025 } 01026 01027 01028 DWORD 01029 GetModuleFileNameA (HINSTANCE hModule, LPSTR lpFilename, DWORD nSize) 01030 { 01031 wchar_t *filename_w; 01032 char *filename_c; 01033 DWORD len; 01034 01035 if (nSize == 0) 01036 { 01037 /* Windows XP/2000. */ 01038 SetLastError (0); 01039 return 0; 01040 } 01041 01042 filename_w = malloc (sizeof (wchar_t) * nSize); 01043 if (! filename_w) 01044 return 0; 01045 01046 len = GetModuleFileNameW (hModule, filename_w, nSize); 01047 if (len == 0) 01048 { 01049 /* Note: If we fail with ERROR_INSUFFICIENT_BUFFER, this is still 01050 (approximately) correct. */ 01051 free (filename_w); 01052 return 0; 01053 } 01054 01055 filename_w[nSize - 1] = '\0'; 01056 filename_c = _dbus_win_utf16_to_utf8 (filename_w, NULL); 01057 free (filename_w); 01058 if (! filename_c) 01059 return 0; 01060 01061 strncpy (lpFilename, filename_c, nSize); 01062 dbus_free (filename_c); 01063 lpFilename[nSize - 1] = '\0'; 01064 /* strlen is correct (not _mbstrlen), because we want storage and 01065 not string length. */ 01066 return strlen (lpFilename); 01067 } 01068 01069 01070 DWORD 01071 GetTempPathA (DWORD nBufferLength, LPSTR lpBuffer) 01072 { 01073 wchar_t dummy[1]; 01074 DWORD len; 01075 01076 len = GetTempPathW (0, dummy); 01077 if (len == 0) 01078 return 0; 01079 01080 _dbus_assert (len <= MAX_PATH); 01081 01082 /* Better be safe than sorry. MSDN doesn't say if len is with or 01083 without terminating 0. */ 01084 len++; 01085 01086 { 01087 wchar_t *buffer_w; 01088 DWORD len_w; 01089 char *buffer_c; 01090 DWORD len_c; 01091 01092 buffer_w = malloc (sizeof (wchar_t) * len); 01093 if (! buffer_w) 01094 return 0; 01095 01096 len_w = GetTempPathW (len, buffer_w); 01097 /* Give up if we still can't get at it. */ 01098 if (len_w == 0 || len_w >= len) 01099 { 01100 free (buffer_w); 01101 return 0; 01102 } 01103 01104 /* Better be really safe. */ 01105 buffer_w[len_w] = '\0'; 01106 01107 buffer_c = _dbus_win_utf16_to_utf8 (buffer_w, NULL); 01108 free (buffer_w); 01109 if (! buffer_c) 01110 return 0; 01111 01112 /* strlen is correct (not _mbstrlen), because we want storage and 01113 not string length. */ 01114 len_c = strlen (buffer_c) + 1; 01115 if (len_c > nBufferLength) 01116 return len_c; 01117 01118 strcpy (lpBuffer, buffer_c); 01119 dbus_free (buffer_c); 01120 return len_c - 1; 01121 } 01122 } 01123 01124 01125 BOOL 01126 SHGetSpecialFolderPathA (HWND hwndOwner, LPSTR lpszPath, int nFolder, 01127 BOOL fCreate) 01128 { 01129 wchar_t path[MAX_PATH]; 01130 char *path_c; 01131 BOOL result; 01132 01133 path[0] = (wchar_t) 0; 01134 result = SHGetSpecialFolderPathW (hwndOwner, path, nFolder, fCreate); 01135 /* Note: May return false even if succeeds. */ 01136 01137 path[MAX_PATH - 1] = (wchar_t) 0; 01138 path_c = _dbus_win_utf16_to_utf8 (path, NULL); 01139 if (! path_c) 01140 return 0; 01141 01142 strncpy (lpszPath, path_c, MAX_PATH); 01143 dbus_free (path_c); 01144 lpszPath[MAX_PATH - 1] = '\0'; 01145 return result; 01146 } 01147 01148 01149 void 01150 OutputDebugStringA (LPCSTR lpOutputString) 01151 { 01152 wchar_t *str; 01153 HANDLE result; 01154 int err; 01155 01156 str = _dbus_win_utf8_to_utf16 (lpOutputString, NULL); 01157 if (!str) 01158 return; 01159 01160 OutputDebugStringW (str); 01161 01162 err = GetLastError (); 01163 dbus_free (str); 01164 SetLastError (err); 01165 }