Back to index

lightning-sunbird  0.9+nobinonly
nsWinAPIs.cpp
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is mozilla.org code.
00015  *
00016  * The Initial Developer of the Original Code is Jungshik Shin
00017  * <jshin@i18nl10n.com>.  Portions created by the Initial Developer
00018  * are Copyright (C) 2006 the Initial Developer. All Rights Reserved.
00019  *
00020  * Contributor(s):
00021  *
00022  * Alternatively, the contents of this file may be used under the terms of
00023  * either the GNU General Public License Version 2 or later (the "GPL"), or
00024  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00025  * in which case the provisions of the GPL or the LGPL are applicable instead
00026  * of those above. If you wish to allow use of your version of this file only
00027  * under the terms of either the GPL or the LGPL, and not to allow others to
00028  * use your version of this file under the terms of the MPL, indicate your
00029  * decision by deleting the provisions above and replace them with the notice
00030  * and other provisions required by the GPL or the LGPL. If you do not delete
00031  * the provisions above, a recipient may use your version of this file under
00032  * the terms of any one of the MPL, the GPL or the LGPL.
00033  *
00034  * ***** END LICENSE BLOCK ***** */
00035 
00036 #include "nscore.h"
00037 #include "nsString.h"
00038 #include "nsNativeCharsetUtils.h"
00039 
00040 #include "nsWinAPIs.h"
00041 
00042 #include <windows.h>
00043 #include <winerror.h>
00044 
00045 #include <io.h>
00046 #include <stdlib.h>
00047 #include <stdio.h>
00048 #include <direct.h>
00049 
00050 #ifdef WINCE
00051 char *_getdcwd(int drive, char *buffer, int maxlen)
00052 {
00053   return _getcwd(buffer, maxlen);
00054 }
00055 #endif
00056 
00057 static inline void ConvertArg(LPCWSTR str, nsCAutoString &cstr,
00058                               const char* (&ptr))
00059 {
00060     if (str) {                                                
00061         NS_CopyUnicodeToNative(nsDependentString(str), cstr);
00062         ptr = cstr.get();
00063     }                                                        
00064     else                                                     
00065         ptr = NULL;                                          
00066 }
00067 
00068 template <class T>
00069 static inline PRBool SetLengthAndCheck(T &aStr, DWORD aLen)
00070 {
00071     aStr.SetLength(aLen);
00072     if (aStr.Length() != aLen) {
00073         SetLastError(ERROR_OUTOFMEMORY);
00074         return PR_FALSE;
00075     }
00076     return PR_TRUE;
00077 }
00078 
00079 //
00080 // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/getting_system_information.asp
00081 
00082 BOOL WINAPI nsSHGetPathFromIDListW(LPCITEMIDLIST aIdList, LPWSTR aPathW)
00083 {
00084     if (aPathW)  {
00085         char pathA[MAX_PATH];
00086         if (SHGetPathFromIDListA(aIdList, pathA)) {
00087             NS_ConvertAtoW(pathA, MAX_PATH, aPathW);
00088             return TRUE;
00089         }
00090     }
00091 
00092     return FALSE;
00093 }
00094 
00095 // GetSystemDirectory, GetWindowsDirectory, GetTempPath, GetEnvironmentVariable 
00096 // return the required buffer size including the terminating null if the buffer 
00097 // passed is too small to hold the result while they return the number of 
00098 // characters stored in the buffer excluding the terminating null if it's 
00099 // large enough. Therefore, just checking whether the return value is zero 
00100 // is not sufficient. We also need to make sure that the return value  is 
00101 // smaller than the buffer size passed to them.
00102 UINT WINAPI nsGetSystemDirectoryW(LPWSTR aPathW, UINT aSize)
00103 {
00104     char pathA[MAX_PATH];
00105     int len;
00106 
00107     if (aPathW && GetSystemDirectoryA(pathA, MAX_PATH) < MAX_PATH && 
00108         (len = NS_ConvertAtoW(pathA, aSize, aPathW)))
00109         return len - 1; // terminating null is not included
00110     else 
00111         return 0;
00112 }
00113 
00114 UINT WINAPI nsGetWindowsDirectoryW(LPWSTR aPathW, UINT aSize)
00115 {
00116     char pathA[MAX_PATH];
00117     int len;
00118 
00119     if (aPathW && GetWindowsDirectoryA(pathA, MAX_PATH) < MAX_PATH && 
00120         (len = NS_ConvertAtoW(pathA, aSize, aPathW)))
00121         return len - 1; // terminating null is not included
00122     else 
00123         return 0;
00124 }
00125 
00126 DWORD WINAPI nsGetTempPathW(DWORD aLen, LPWSTR aPathW)
00127 {
00128 #ifdef WINCE
00129     char *pathA = "\\temp";
00130     DWORD len = NS_ConvertAtoW(pathA, aLen, aPathW);
00131     return len-1;
00132 #else
00133     char pathA[MAX_PATH];
00134     DWORD len;
00135     if (aPathW && GetTempPathA(MAX_PATH, pathA) < MAX_PATH &&
00136         (len = NS_ConvertAtoW(pathA, aLen, aPathW)))
00137         return len - 1; // terminating null is not included
00138     return 0;
00139 #endif
00140 }
00141 
00142 
00143 DWORD WINAPI nsGetEnvironmentVariableW(LPCWSTR aName, LPWSTR aValue, DWORD aSize)
00144 {
00145 
00146     if (!aName || !aValue || aSize <= 0)
00147         return 0;
00148 
00149     nsCAutoString nameA;
00150     NS_CopyUnicodeToNative(nsDependentString(aName), nameA); 
00151 
00152     const DWORD maxValueLen = 32767; // the maximum length of an env. variable
00153     nsCAutoString value;
00154     DWORD sizeA = NS_MIN(maxValueLen, aSize * 2);
00155     if (!SetLengthAndCheck(value, sizeA))
00156         return 0;
00157     char *buf = value.BeginWriting();
00158     DWORD len;
00159     if (!(len = GetEnvironmentVariableA((char*)nameA.get(), buf, sizeA)))
00160         return 0;
00161 
00162     if (len > sizeA) {
00163         if (sizeA < maxValueLen) {
00164             if (!SetLengthAndCheck(value, len))
00165                 return 0;
00166             buf = value.BeginWriting();
00167             len = GetEnvironmentVariableA((char*)nameA.get(), buf, len);
00168         }
00169         else 
00170             // sizeA >= maxValueLen and still failed. 
00171             return 0;
00172     }
00173 
00174     // terminating null is not included in the length
00175     return (len = NS_ConvertAtoW(buf, aSize, aValue)) ? len - 1 : 0;
00176 }
00177 
00178 BOOL WINAPI nsCreateDirectoryW(LPCWSTR aPath, LPSECURITY_ATTRIBUTES aSecAttr)
00179 {
00180     if (!aPath) {
00181         SetLastError(ERROR_BAD_ARGUMENTS);
00182         return FALSE;
00183     }
00184 
00185     nsCAutoString pathA;
00186     NS_CopyUnicodeToNative(nsDependentString(aPath), pathA);
00187     return CreateDirectoryA(pathA.get(), aSecAttr);
00188 }
00189 
00190 HANDLE WINAPI nsCreateFileW(LPCWSTR aPath, DWORD aAccess,
00191                             DWORD aMode, LPSECURITY_ATTRIBUTES aSecAttr,
00192                             DWORD aCreat, DWORD aFlags, HANDLE aTemplate)
00193 {
00194     if (!aPath) {
00195         SetLastError(ERROR_BAD_ARGUMENTS);
00196         return INVALID_HANDLE_VALUE;
00197     }
00198 
00199     nsCAutoString pathA;
00200     NS_CopyUnicodeToNative(nsDependentString(aPath), pathA);
00201     return CreateFileA(pathA.get(), aAccess, aMode, aSecAttr, aCreat, 
00202                        aFlags, aTemplate);
00203 }
00204 
00205 HINSTANCE WINAPI nsShellExecuteW(HWND aWin, LPCWSTR aOp, LPCWSTR aFile,
00206                                  LPCWSTR aParam, LPCWSTR aDir, INT aShowCmd)
00207 {
00208     nsCAutoString op, file, param, dir;
00209     const char  *pOp, *pFile, *pParam, *pDir;
00210 
00211     ConvertArg(aOp, op, pOp);
00212     ConvertArg(aFile, file, pFile);
00213     ConvertArg(aParam, param, pParam);
00214     ConvertArg(aDir, dir, pDir);
00215 
00216     return ShellExecuteA(aWin, pOp, pFile, pParam, pDir, aShowCmd);
00217 }
00218 
00219 BOOL WINAPI nsCopyFileW(LPCWSTR aSrc, LPCWSTR aDest, BOOL aNoOverwrite)
00220 {
00221     nsCAutoString src, dest;
00222     const char *pSrc, *pDest;
00223 
00224     ConvertArg(aSrc, src, pSrc);
00225     ConvertArg(aDest, dest, pDest);
00226 
00227     return CopyFileA(pSrc, pDest, aNoOverwrite);
00228 }
00229 
00230 BOOL WINAPI nsMoveFileW(LPCWSTR aSrc, LPCWSTR aDest)
00231 {
00232     nsCAutoString src, dest;
00233     const char *pSrc, *pDest;
00234 
00235     ConvertArg(aSrc, src, pSrc);
00236     ConvertArg(aDest, dest, pDest);
00237 
00238     return MoveFileA(pSrc, pDest);
00239 }
00240 
00241 // To work around the problem with misconfigured tinderboxes (bug 331433)
00242 #ifndef WINCE
00243 #if defined(_MSC_VER) && _MSC_VER <= 0x1200
00244 #define GetFileVersionInfoA(aPath, aHandle, aLen, aData) \
00245         GetFileVersionInfoA((LPSTR)aPath, aHandle, aLen, aData)
00246 #define GetFileVersionInfoSizeA(aPath, aHandle) \
00247         GetFileVersionInfoSizeA((LPSTR)aPath, aHandle)
00248 #define GetFileVersionInfoW ((nsGetFileVersionInfo)GetFileVersionInfoW)
00249 #define GetFileVersionInfoSizeW \
00250         ((nsGetFileVersionInfoSize)GetFileVersionInfoSizeW)
00251 #endif
00252 #endif
00253 
00254 BOOL WINAPI nsGetFileVersionInfoW(LPCWSTR aPath, DWORD aHandle, DWORD aLen,
00255                                   LPVOID aData)
00256 {
00257     nsCAutoString path;
00258     const char *pPath;
00259     ConvertArg(aPath, path, pPath);
00260     return GetFileVersionInfoA(pPath, aHandle, aLen, aData);
00261 }
00262 
00263 DWORD WINAPI nsGetFileVersionInfoSizeW(LPCWSTR aPath, LPDWORD aHandle)
00264 {
00265     nsCAutoString path;
00266     const char *pPath;
00267     ConvertArg(aPath, path, pPath);
00268     return GetFileVersionInfoSizeA(pPath, aHandle);
00269 }
00270 
00271 DWORD WINAPI nsGetFileAttributesW(LPCWSTR aPath)
00272 {
00273     nsCAutoString path;
00274     const char *pPath;
00275     ConvertArg(aPath, path, pPath);
00276     return GetFileAttributesA(pPath);
00277 }
00278 
00279 BOOL WINAPI nsGetFileAttributesExW(LPCWSTR aPath, GET_FILEEX_INFO_LEVELS aLevel,
00280                                    LPVOID aInfo)
00281 {
00282     NS_ASSERTION(aLevel == GetFileExInfoStandard, "invalid level specified");
00283 #ifndef WINCE
00284     NS_ASSERTION(nsWinAPIs::mCopyFile != CopyFileW, 
00285                  "Win APIs pointers are reset to the stubs of 'W' APIs");
00286 #endif
00287     nsCAutoString path;
00288     const char *pPath;
00289     ConvertArg(aPath, path, pPath);
00290 
00291     // present on Win 98/ME
00292     if (nsWinAPIs::mGetFileAttributesExA)
00293 #ifdef DEBUG_jungshik
00294     {
00295         BOOL rv = nsWinAPIs::mGetFileAttributesExA(pPath, aLevel, aInfo);
00296         if (!rv) {
00297             printf("nsGetFileAttributesExW with file=%s failed\n", pPath);
00298             printf("Last error is %d\n", GetLastError());
00299         }
00300         return rv;
00301     }
00302 #else
00303         return nsWinAPIs::mGetFileAttributesExA(pPath, aLevel, aInfo);
00304 #endif
00305     // fallback for Win95 without IE4 or later where GetFileAttributesEx 
00306     // is missing. 
00307     
00308     if (aLevel != GetFileExInfoStandard) {
00309         SetLastError(ERROR_INVALID_PARAMETER);
00310         return FALSE;
00311     }
00312 
00313     // FindFirstFile expands wildcard characters so that we need to make
00314     // sure that the path contains no wildcard.
00315     if (NULL != wcspbrk(aPath, L"?*")) 
00316         return FALSE;
00317 
00318     WIN32_FIND_DATAA fdata;
00319     HANDLE handle = FindFirstFileA(pPath, &fdata);
00320     if (handle == INVALID_HANDLE_VALUE)
00321         return FALSE;
00322     // XXX : FindFirstFile doesn't work with a root directory
00323     // or a path ending with a slash/back slash.
00324     // We can work around it as in NSPR (w95io.c), but don't bother
00325     // because Windows 95 without IE4 or later is a rare beast so that
00326     // it's not worth duplicating ~40 lines of the NSPR code here to 
00327     // support a path ending with a slash/back slash or a root path. 
00328     // Note that even MS's emulation of GetFileAttributesEx for Win95
00329     // (included in Visual C++) doesn't, either.
00330 
00331     WIN32_FILE_ATTRIBUTE_DATA *fadata= 
00332         (WIN32_FILE_ATTRIBUTE_DATA *) aInfo;
00333 
00334     fadata->dwFileAttributes = fdata.dwFileAttributes;
00335     fadata->ftCreationTime = fdata.ftCreationTime;
00336     fadata->ftLastAccessTime = fdata.ftLastAccessTime;
00337     fadata->ftLastWriteTime = fdata.ftLastWriteTime;
00338     fadata->nFileSizeHigh = fdata.nFileSizeHigh;
00339     fadata->nFileSizeLow = fdata.nFileSizeLow;
00340 
00341     FindClose(handle);
00342     return TRUE;
00343 }   
00344 
00345 BOOL WINAPI nsGetFileAttributesExW351(LPCWSTR aPath,
00346                                       GET_FILEEX_INFO_LEVELS aLevel,
00347                                       LPVOID aInfo)
00348 {
00349     NS_ASSERTION(aLevel == GetFileExInfoStandard, "invalid level specified");
00350     if (aLevel != GetFileExInfoStandard) {
00351         SetLastError(ERROR_INVALID_PARAMETER);
00352         return FALSE;
00353     }
00354 
00355     // FindFirstFile expands wildcard characters so that we need to make
00356     // sure that the path contains no wildcard.
00357     if (NULL != wcspbrk(aPath, L"?*")) 
00358         return FALSE;
00359 
00360     WIN32_FIND_DATAW fdata;
00361     HANDLE handle = FindFirstFileW(aPath, &fdata);
00362     if (handle == INVALID_HANDLE_VALUE)
00363         return FALSE;
00364 
00365     WIN32_FILE_ATTRIBUTE_DATA *fadata = 
00366         (WIN32_FILE_ATTRIBUTE_DATA *) aInfo;
00367 
00368     fadata->dwFileAttributes = fdata.dwFileAttributes;
00369     fadata->ftCreationTime = fdata.ftCreationTime;
00370     fadata->ftLastAccessTime = fdata.ftLastAccessTime;
00371     fadata->ftLastWriteTime = fdata.ftLastWriteTime;
00372     fadata->nFileSizeHigh = fdata.nFileSizeHigh;
00373     fadata->nFileSizeLow = fdata.nFileSizeLow;
00374 
00375     FindClose(handle);
00376     return TRUE;
00377 }   
00378 
00379 DWORD WINAPI nsGetShortPathNameW(LPCWSTR aLPath, LPWSTR aSPath, DWORD aLen)
00380 {
00381     if (!aLPath || !aSPath) {
00382         SetLastError(ERROR_BAD_ARGUMENTS);
00383         return 0;
00384     }
00385 
00386     nsCAutoString lPath;
00387     NS_CopyUnicodeToNative(nsDependentString(aLPath), lPath);
00388 
00389     // MAX_PATH is the max path length including the terminating null.
00390     if (lPath.Length() >= MAX_PATH) {
00391         SetLastError(ERROR_BAD_ARGUMENTS);
00392         return 0;
00393     }
00394 
00395     nsCAutoString sPath;
00396     if (!SetLengthAndCheck(sPath, aLen))
00397         return 0;
00398     char *pSpath = sPath.BeginWriting();
00399     DWORD lenA = GetShortPathNameA(lPath.get(), pSpath, aLen);
00400     if (lenA > aLen) {
00401         if (!SetLengthAndCheck(sPath, lenA))
00402             return 0;
00403         pSpath = sPath.BeginWriting();
00404         lenA = GetShortPathNameA(lPath.get(), pSpath, lenA);
00405     }
00406 
00407     if (!lenA) 
00408         return 0;
00409 
00410     // see if |aSPath| is large enough to hold the result
00411     DWORD lenW = NS_ConvertAtoW(pSpath, 0, aSPath);
00412     if (lenW > aLen)
00413         // aSPath is too small. just return the required size.
00414         return lenW; 
00415 
00416     // terminating null is not included in the return value
00417     return (lenW = NS_ConvertAtoW(pSpath, aLen, aSPath)) ? lenW - 1 : 0;
00418 }
00419 
00420 BOOL WINAPI nsGetDiskFreeSpaceW(LPCWSTR aDir, LPDWORD aSpC, LPDWORD aBpS,
00421                                 LPDWORD aNFC, LPDWORD aTNC)
00422 {
00423     nsCAutoString dir;
00424     const char *pDir;
00425     ConvertArg(aDir, dir, pDir);
00426     return GetDiskFreeSpaceA(pDir, aSpC, aBpS, aNFC, aTNC);
00427 }
00428 
00429 typedef BOOL (WINAPI *fpGetDiskFreeSpaceExA)(LPCSTR lpDirectoryName,
00430                                              PULARGE_INTEGER lpFreeBytesAvailableToCaller,
00431                                              PULARGE_INTEGER lpTotalNumberOfBytes,
00432                                              PULARGE_INTEGER lpTotalNumberOfFreeBytes);
00433 
00434 BOOL WINAPI nsGetDiskFreeSpaceExW(LPCWSTR aDir, PULARGE_INTEGER aFBA,
00435                                   PULARGE_INTEGER aTNB, PULARGE_INTEGER aTNFB)
00436 {
00437     // Attempt to check disk space using the GetDiskFreeSpaceExA function. 
00438     // --- FROM MSDN ---
00439     // The GetDiskFreeSpaceEx function is available beginning with Windows 95 OEM Service 
00440     // Release 2 (OSR2). To determine whether GetDiskFreeSpaceEx is available, call 
00441     // GetModuleHandle to get the handle to Kernel32.dll. Then you can call GetProcAddress. 
00442     // It is not necessary to call LoadLibrary on Kernel32.dll because it is already loaded 
00443     // into every process address space.
00444     fpGetDiskFreeSpaceExA pGetDiskFreeSpaceExA = (fpGetDiskFreeSpaceExA)
00445         GetProcAddress(GetModuleHandle("kernel32.dll"), "GetDiskFreeSpaceExA");
00446     if (!pGetDiskFreeSpaceExA)
00447         return 0;
00448 
00449     nsCAutoString dir;
00450     const char *pDir;
00451     ConvertArg(aDir, dir, pDir);
00452     return pGetDiskFreeSpaceExA(pDir, aFBA, aTNB, aTNFB);
00453 }
00454 
00455 DWORD WINAPI nsGetModuleFileNameW(HMODULE aModule, LPWSTR aName, DWORD aSize)
00456 {
00457     if (!aName || aSize <= 0) {
00458         SetLastError(ERROR_BAD_ARGUMENTS);
00459         return 0;
00460     }
00461 
00462     DWORD len;
00463     char buf[MAX_PATH + 1];
00464     if (!(len = GetModuleFileNameA(aModule, buf, MAX_PATH)))
00465         return 0;
00466     // just in case, null-terminate
00467     buf[MAX_PATH] = '\0';
00468 
00469     len = NS_ConvertAtoW(buf, 0, aName);
00470     if (len <= aSize) 
00471         return (len = NS_ConvertAtoW(buf, aSize, aName)) ? len - 1 : 0;
00472 
00473     // buffer is not large enough. just truncate the result to the first
00474     // |aSize| characters.
00475     nsAutoString temp;
00476     if (!SetLengthAndCheck(temp, len))
00477         return 0;
00478     PRUnichar *pTmp = temp.BeginWriting();
00479     NS_ConvertAtoW(buf, len, pTmp);
00480     memcpy(aName, pTmp, aSize * 2);
00481     SetLastError(ERROR_INSUFFICIENT_BUFFER);
00482     return aSize;
00483 }
00484 
00485 wchar_t* nsGetCwdW(wchar_t *aBuf, int aMaxLen)
00486 {
00487     if (aMaxLen <= 0)
00488         return NULL;
00489 
00490     // One 16-bit unit in UTF-16 can take as many as 2 bytes in legacy Windows 
00491     // codepage used on Windows 9x/ME (note that we don't have to worry about
00492     // UTF-8 and GB18030 because they're not used on Windows 9x/ME)
00493     char *cwdA = _getcwd(NULL, aMaxLen * 2);
00494     if (!cwdA)
00495         return NULL;
00496 
00497     // see if we're given a buffer large enough to hold the result
00498     int len = NS_ConvertAtoW(cwdA, 0, aBuf);
00499     if ((len  > aMaxLen && aBuf) || len == 0) {
00500         free(cwdA);
00501         return NULL;
00502     }
00503 
00504     if (!aBuf)
00505         // errno = ENOMEM;
00506         aBuf = (wchar_t *) malloc(len * sizeof(wchar_t));
00507 
00508     if (!aBuf) {
00509         free(cwdA);
00510         return NULL;
00511     }
00512 
00513     len = NS_ConvertAtoW(cwdA, NS_MAX(len, aMaxLen), aBuf); 
00514     free(cwdA);
00515     return len ? aBuf : NULL;
00516 }
00517 
00518 wchar_t* nsGetDCwdW(int aDrive, wchar_t *aBuf, int aMaxLen)
00519 {
00520     if (aMaxLen <= 0)
00521         return NULL;
00522 
00523     // One 16-bit unit in UTF-16 can take as many as 2 bytes in legacy Windows codepage
00524     // used on Windows 9x/ME (note that we don't have to worry about 
00525     // UTF-8 and GB18030 because they're not used on Windows 9x/ME)
00526     char *cwdA = _getdcwd(aDrive, NULL, aMaxLen * 2);
00527     if (!cwdA)
00528         return NULL;
00529 
00530     // see if we're given a buffer large enough to hold the result
00531     int len = NS_ConvertAtoW(cwdA, 0, aBuf);
00532     if ((len  > aMaxLen && aBuf) || len == 0) {
00533         //errno = ERANGE;
00534         free(cwdA);
00535         return NULL;
00536     }
00537 
00538     if (!aBuf)
00539         aBuf = (wchar_t *) malloc(len * sizeof(wchar_t));
00540 
00541     if (!aBuf) {
00542         free(cwdA);
00543         return NULL;
00544     }
00545 
00546     len = NS_ConvertAtoW(cwdA, NS_MAX(len, aMaxLen), aBuf); 
00547     free(cwdA);
00548     return len ? aBuf : NULL;
00549 }
00550 
00551 FILE* nsFopenW(const wchar_t *aPath, const wchar_t *aMode)
00552 {
00553     if (!aPath) return NULL;
00554 
00555     nsCAutoString pathA;
00556     NS_CopyUnicodeToNative(nsDependentString(aPath), pathA);
00557 
00558     return fopen(pathA.get(),
00559                  NS_LossyConvertUTF16toASCII(aMode).get());
00560 }
00561 
00562 int nsRemoveW(const wchar_t *aPath)
00563 {
00564     if (!aPath) return -1;
00565 
00566     nsCAutoString pathA;
00567     NS_CopyUnicodeToNative(nsDependentString(aPath), pathA);
00568 
00569     return remove(pathA.get());
00570 }
00571 
00572 int nsRmdirW(const wchar_t *aPath)
00573 {
00574     if (!aPath) return -1;
00575 
00576     nsCAutoString pathA;
00577     NS_CopyUnicodeToNative(nsDependentString(aPath), pathA);
00578 
00579     return _rmdir(pathA.get());
00580 }
00581 
00582 int nsChmodW(const wchar_t *aPath, int aMode)
00583 {
00584     if (!aPath) return -1;
00585 
00586     nsCAutoString pathA;
00587     NS_CopyUnicodeToNative(nsDependentString(aPath), pathA);
00588 
00589     return _chmod(pathA.get(), aMode);
00590 }
00591 
00592 
00593 #ifdef WINCE
00594 PRBool                     nsWinAPIs::sUseUnicode        = 0;
00595 nsSHGetPathFromIDList      nsWinAPIs::mSHGetPathFromIDList = nsSHGetPathFromIDListW;
00596 nsGetSystemDirectory       nsWinAPIs::mGetSystemDirectory = GetSystemDirectoryW;
00597 nsGetWindowsDirectory      nsWinAPIs::mGetWindowsDirectory = GetWindowsDirectoryW;
00598 nsGetTempPath              nsWinAPIs::mGetTempPath = GetTempPathW;
00599 nsGetEnvironmentVariable   nsWinAPIs::mGetEnvironmentVariable = GetEnvironmentVariableW;
00600 nsCreateDirectory          nsWinAPIs::mCreateDirectory = CreateDirectoryW;
00601 nsCreateFile               nsWinAPIs::mCreateFile = CreateFileW;
00602 nsShellExecute             nsWinAPIs::mShellExecute = ShellExecuteW;
00603 nsCopyFile                 nsWinAPIs::mCopyFile = CopyFileW;
00604 nsMoveFile                 nsWinAPIs::mMoveFile = MoveFileW;
00605 nsGetFileVersionInfo       nsWinAPIs::mGetFileVersionInfo = nsGetFileVersionInfoW;
00606 nsGetFileVersionInfoSize   nsWinAPIs::mGetFileVersionInfoSize = nsGetFileVersionInfoSizeW;
00607 nsGetFileAttributes        nsWinAPIs::mGetFileAttributes = GetFileAttributesW;
00608 nsGetFileAttributesEx      nsWinAPIs::mGetFileAttributesEx = nsGetFileAttributesExW;
00609 nsGetFileAttributesExA     nsWinAPIs::mGetFileAttributesExA = NULL;
00610 nsGetShortPathName         nsWinAPIs::mGetShortPathName = nsGetShortPathNameW;    
00611 nsGetDiskFreeSpace         nsWinAPIs::mGetDiskFreeSpace = nsGetDiskFreeSpaceW;     
00612 nsGetDiskFreeSpaceEx       nsWinAPIs::mGetDiskFreeSpaceEx = nsGetDiskFreeSpaceExW;
00613 nsGetModuleFileName        nsWinAPIs::mGetModuleFileName = GetModuleFileNameW;
00614 nsGetCwd                   nsWinAPIs::mGetCwd = nsGetCwdW; 
00615 nsGetDCwd                  nsWinAPIs::mGetDCwd = nsGetDCwdW; 
00616 nsFopen                    nsWinAPIs::mFopen = nsFopenW;
00617 nsRemove                   nsWinAPIs::mRemove = nsRemoveW;
00618 nsRmdir                    nsWinAPIs::mRmdir = nsRmdirW;
00619 nsChmod                    nsWinAPIs::mChmod = nsChmodW;
00620 
00621 #else
00622 PRBool nsWinAPIs::sUseUnicode        = -1;  // not yet initialized
00623 
00624 // All but three APIs are initialized to 'W' versions. 
00625 // Exceptions are SHGetPathFromIDList, GetFileAttributesEx, GetFreeDiskSpaceEx 
00626 // for which even stubs are not available on Win95 so that we set
00627 // them to our own implementation initially. Yet another exception needs to be
00628 // made for GetFileAttributesEx because even its 'A' version doesn't exist on
00629 // Win95. The corresponding function pointer is set to NULL initially 
00630 // and its existence is checked using GetProcAddress on Win 9x/ME.
00631 nsSHGetPathFromIDList      nsWinAPIs::mSHGetPathFromIDList = nsSHGetPathFromIDListW;
00632 nsGetSystemDirectory       nsWinAPIs::mGetSystemDirectory = GetSystemDirectoryW;
00633 nsGetWindowsDirectory      nsWinAPIs::mGetWindowsDirectory = GetWindowsDirectoryW;
00634 nsGetTempPath              nsWinAPIs::mGetTempPath = GetTempPathW;
00635 nsGetEnvironmentVariable   nsWinAPIs::mGetEnvironmentVariable = GetEnvironmentVariableW;
00636 nsCreateDirectory          nsWinAPIs::mCreateDirectory = CreateDirectoryW;
00637 nsCreateFile               nsWinAPIs::mCreateFile = CreateFileW;
00638 nsShellExecute             nsWinAPIs::mShellExecute = ShellExecuteW;
00639 nsCopyFile                 nsWinAPIs::mCopyFile = CopyFileW;
00640 nsMoveFile                 nsWinAPIs::mMoveFile = MoveFileW;
00641 nsGetFileVersionInfo       nsWinAPIs::mGetFileVersionInfo = GetFileVersionInfoW;
00642 nsGetFileVersionInfoSize   nsWinAPIs::mGetFileVersionInfoSize = GetFileVersionInfoSizeW;
00643 nsGetFileAttributes        nsWinAPIs::mGetFileAttributes = GetFileAttributesW;
00644 nsGetFileAttributesEx      nsWinAPIs::mGetFileAttributesEx = nsGetFileAttributesExW;
00645 nsGetFileAttributesExA     nsWinAPIs::mGetFileAttributesExA = NULL;
00646 nsGetShortPathName         nsWinAPIs::mGetShortPathName = GetShortPathNameW;    
00647 nsGetDiskFreeSpace         nsWinAPIs::mGetDiskFreeSpace = GetDiskFreeSpaceW;     
00648 nsGetDiskFreeSpaceEx       nsWinAPIs::mGetDiskFreeSpaceEx = nsGetDiskFreeSpaceExW;
00649 nsGetModuleFileName        nsWinAPIs::mGetModuleFileName = GetModuleFileNameW;
00650 
00651 
00652 nsGetCwd                   nsWinAPIs::mGetCwd = _wgetcwd; 
00653 nsGetDCwd                  nsWinAPIs::mGetDCwd = _wgetdcwd; 
00654 nsFopen                    nsWinAPIs::mFopen = _wfopen;
00655 nsRemove                   nsWinAPIs::mRemove = _wremove;
00656 nsRmdir                    nsWinAPIs::mRmdir = _wrmdir;
00657 nsChmod                    nsWinAPIs::mChmod = _wchmod;
00658 
00659 #endif
00660 
00661 // This is a dummy variable to make sure that WinAPI is initialized 
00662 // at the very start. Note that |sDummy| must be defined AFTER
00663 // all the function pointers for Win APIs are defined. Otherwise,
00664 // what's done in |GlobalInit| would have no effect.
00665 PRBool nsWinAPIs::sDummy = nsWinAPIs::GlobalInit();
00666 
00667 PRBool
00668 nsWinAPIs::GlobalInit()
00669 {
00670 #ifndef WINCE
00671     // Find out if we are running on a unicode enabled version of Windows
00672     OSVERSIONINFOA osvi = {0};
00673     osvi.dwOSVersionInfoSize = sizeof(osvi);
00674     if (!GetVersionExA(&osvi)) {
00675       sUseUnicode = PR_FALSE;
00676     } else {
00677       sUseUnicode = (osvi.dwPlatformId >= VER_PLATFORM_WIN32_NT);
00678     }
00679 
00680 #ifdef DEBUG
00681   // In debug builds, allow explicit use of ANSI methods for testing purposes.
00682    if (getenv("WINAPI_USE_ANSI"))
00683        sUseUnicode = PR_FALSE;
00684 #endif
00685 
00686     HINSTANCE kernel32 = ::GetModuleHandle("kernel32.dll");
00687 
00688     // on Win 9x/ME, use our own implementations of 'W' APIs
00689     // which eventually calls 'A' APIs
00690     if (!sUseUnicode) {
00691         NS_WARNING("Windows 'A' APIs will be used !!");
00692         mGetSystemDirectory = nsGetSystemDirectoryW;
00693         mGetWindowsDirectory = nsGetWindowsDirectoryW;
00694         mGetTempPath = nsGetTempPathW;
00695         mGetEnvironmentVariable = nsGetEnvironmentVariableW;
00696         mCreateFile = nsCreateFileW;
00697         mCreateDirectory = nsCreateDirectoryW;
00698         mShellExecute = nsShellExecuteW;
00699         mCopyFile = nsCopyFileW;
00700         mMoveFile = nsMoveFileW;
00701         mGetFileVersionInfo = nsGetFileVersionInfoW;
00702         mGetFileVersionInfoSize = nsGetFileVersionInfoSizeW;
00703         mGetFileAttributes = nsGetFileAttributesW;
00704         mGetShortPathName = nsGetShortPathNameW;
00705         mGetDiskFreeSpace = nsGetDiskFreeSpaceW;
00706         mGetModuleFileName = nsGetModuleFileNameW;
00707        
00708         mGetCwd = nsGetCwdW;
00709         mGetDCwd = nsGetDCwdW;
00710         mFopen  = nsFopenW;
00711         mRemove  = nsRemoveW;
00712         mRmdir  = nsRmdirW;
00713         mChmod  = nsChmodW;
00714 
00715         // absent on Win 95. 
00716         mGetFileAttributesExA = (nsGetFileAttributesExA)
00717             GetProcAddress(kernel32, "GetFileAttributesExA");
00718     } 
00719     else {
00720         HINSTANCE shell32 = LoadLibrary("Shell32.dll");
00721         if (shell32) 
00722             mSHGetPathFromIDList = (nsSHGetPathFromIDList)
00723                 GetProcAddress(shell32, "SHGetPathFromIDListW");
00724         NS_ASSERTION(mSHGetPathFromIDList, "failed to get proc. address");
00725         mGetDiskFreeSpaceEx = (nsGetDiskFreeSpaceEx)
00726             GetProcAddress(kernel32, "GetDiskFreeSpaceExW");
00727         mGetFileAttributesEx = (nsGetFileAttributesEx)
00728             GetProcAddress(kernel32, "GetFileAttributesExW");
00729         if (!mGetFileAttributesEx)
00730             mGetFileAttributesEx = nsGetFileAttributesExW351;
00731     }
00732 
00733 #endif // WINCE
00734     return PR_TRUE;
00735 }
00736 
00737 NS_COM PRBool 
00738 NS_UseUnicode()
00739 {
00740     return nsWinAPIs::sUseUnicode; 
00741 }