Subversion Repositories autosfx

Rev

Blame | Last modification | View Log | RSS feed

  1. #include "stdafx.h"
  2. #pragma hdrstop
  3. #if defined(UNICODE) && defined(ALLOW_WIN98)
  4. /* ***** BEGIN LICENSE BLOCK *****
  5.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  6.  *
  7.  * The contents of this file are subject to the Mozilla Public License Version
  8.  * 1.1 (the "License"); you may not use this file except in compliance with
  9.  * the License. You may obtain a copy of the License at
  10.  * http://www.mozilla.org/MPL/
  11.  *
  12.  * Software distributed under the License is distributed on an "AS IS" basis,
  13.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  14.  * for the specific language governing rights and limitations under the
  15.  * License.
  16.  *
  17.  * The Original Code is for Open Layer for Unicode (opencow).
  18.  *
  19.  * The Initial Developer of the Original Code is Brodie Thiesfield.
  20.  * Portions created by the Initial Developer are Copyright (C) 2004
  21.  * the Initial Developer. All Rights Reserved.
  22.  *
  23.  * Contributor(s):
  24.  *
  25.  * Alternatively, the contents of this file may be used under the terms of
  26.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  27.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  28.  * in which case the provisions of the GPL or the LGPL are applicable instead
  29.  * of those above. If you wish to allow use of your version of this file only
  30.  * under the terms of either the GPL or the LGPL, and not to allow others to
  31.  * use your version of this file under the terms of the MPL, indicate your
  32.  * decision by deleting the provisions above and replace them with the notice
  33.  * and other provisions required by the GPL or the LGPL. If you do not delete
  34.  * the provisions above, a recipient may use your version of this file under
  35.  * the terms of any one of the MPL, the GPL or the LGPL.
  36.  *
  37.  * ***** END LICENSE BLOCK ***** */
  38. /************************************************************************
  39.  Copyright (C) 2009, 2010  by Russell J. Peters, Roger Aelbrecht
  40.  
  41.    This file is part of TZipMaster Version 1.9.
  42.  
  43.     TZipMaster is free software: you can redistribute it and/or modify
  44.     it under the terms of the GNU Lesser General Public License as published by
  45.     the Free Software Foundation, either version 3 of the License, or
  46.     (at your option) any later version.
  47.  
  48.     TZipMaster is distributed in the hope that it will be useful,
  49.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  50.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  51.     GNU Lesser General Public License for more details.
  52.  
  53.     You should have received a copy of the GNU Lesser General Public License
  54.     along with TZipMaster.  If not, see <http://www.gnu.org/licenses/>.
  55.  
  56.     contact: problems@delphizip.org (include ZipMaster in the subject).
  57.     updates: http://www.delphizip.org
  58.     DelphiZip maillist subscribe at http://www.freelists.org/list/delphizip
  59. ************************************************************************/
  60.  
  61. // define these symbols so that we don't get dllimport linkage
  62. // from the system headers
  63. #define _KERNEL32_
  64.  
  65. #include <windows.h>
  66. #include <mbstring.h>
  67.  
  68. #include "MbcsBuffer.h"
  69.  
  70. // ----------------------------------------------------------------------------
  71. // Definitions
  72.  
  73. #ifndef INVALID_FILE_ATTRIBUTES
  74. # define INVALID_FILE_ATTRIBUTES    ((DWORD)-1)
  75. #endif
  76. #ifndef IS_INTRESOURCE
  77. # define IS_INTRESOURCE(p)          (((unsigned long)(p) >> 16) == 0UL)
  78. #endif
  79.  
  80. #if defined(__BORLANDC__) && (__BORLANDC__ < 0x0570)                              
  81. #define  __in_opt IN
  82. #define  __out    OUT
  83. #define  __in     IN
  84. #define  __out_opt OUT
  85. #endif
  86. // ----------------------------------------------------------------------------
  87. // Globals
  88.  
  89. //extern HINSTANCE g_hInstanceDLL;
  90. //extern int       g_nDebug;
  91.  
  92. // ----------------------------------------------------------------------------
  93. // API
  94. #if 0
  95. ATOM WINAPI
  96. AddAtomW(
  97.     IN LPCWSTR lpString
  98.     )
  99. {
  100.     CMbcsBuffer mbcsString;
  101.     if (!mbcsString.FromUnicode(lpString))
  102.         return 0;
  103.  
  104.     return ::AddAtomA(mbcsString);
  105. }
  106.  
  107. // BeginUpdateResourceA
  108. // BeginUpdateResourceW
  109. // BuildCommDCBAndTimeoutsW
  110. // BuildCommDCBW
  111. // CallNamedPipeW
  112. // CommConfigDialogW
  113. #endif
  114.  
  115. extern "C" int WINAPI
  116. zCompareStringW(          
  117.         IN LCID Locale,
  118.     IN DWORD dwCmpFlags,
  119.     IN LPCWSTR lpString1,
  120.     IN int cchCount1,
  121.     IN LPCWSTR lpString2,
  122.     IN int cchCount2
  123. )
  124. {
  125.     CMbcsBuffer mbcsString1;
  126.     CMbcsBuffer mbcsString2;
  127.     if (!mbcsString1.FromUnicode(lpString1, cchCount1) || //)
  128.         //return 0;
  129.        
  130.     /*if ( */ !mbcsString2.FromUnicode(lpString2, cchCount2))
  131.         {
  132.                 SetLastError(ERROR_INVALID_PARAMETER);
  133.         return 0;
  134.         }
  135.  
  136.     return ::CompareStringA(Locale, dwCmpFlags, mbcsString1, cchCount1, mbcsString2, cchCount2);
  137. }
  138.  
  139. #if 0
  140. // CopyFileExW
  141.  
  142. BOOL WINAPI
  143. CopyFileW(
  144.     IN LPCWSTR lpExistingFileName,
  145.     IN LPCWSTR lpNewFileName,
  146.     IN BOOL bFailIfExists
  147.     )
  148. {
  149.     CMbcsBuffer mbcsExistingFileName;
  150.     if (!mbcsExistingFileName.FromUnicode(lpExistingFileName))
  151.         return FALSE;
  152.  
  153.     CMbcsBuffer mbcsNewFileName;
  154.     if (!mbcsNewFileName.FromUnicode(lpNewFileName))
  155.         return FALSE;
  156.  
  157.     return ::CopyFileA(mbcsExistingFileName, mbcsNewFileName, bFailIfExists);
  158. }
  159.  
  160. BOOL WINAPI
  161. CreateDirectoryExW(
  162.     IN LPCWSTR lpTemplateDirectory,
  163.     IN LPCWSTR lpNewDirectory,
  164.     IN LPSECURITY_ATTRIBUTES lpSecurityAttributes
  165.     )
  166. {
  167.     CMbcsBuffer mbcsTemplateDirectory;
  168.     if (!mbcsTemplateDirectory.FromUnicode(lpTemplateDirectory))
  169.         return FALSE;
  170.  
  171.     CMbcsBuffer mbcsNewDirectory;
  172.     if (!mbcsNewDirectory.FromUnicode(lpNewDirectory))
  173.         return FALSE;
  174.  
  175.     return ::CreateDirectoryExA(mbcsTemplateDirectory, mbcsNewDirectory, lpSecurityAttributes);
  176. }
  177. #endif
  178. extern "C" BOOL WINAPI
  179. zCreateDirectoryW(
  180.     IN LPCWSTR lpPathName,
  181.     IN LPSECURITY_ATTRIBUTES lpSecurityAttributes
  182.     )
  183. {
  184.     CMbcsBuffer mbcsPathName;
  185.     if (!mbcsPathName.FromUnicode(lpPathName))
  186.         return FALSE;
  187.  
  188.     return ::CreateDirectoryA(mbcsPathName, lpSecurityAttributes);
  189. }
  190. #if 0
  191. HANDLE WINAPI
  192. CreateEventW(
  193.     IN LPSECURITY_ATTRIBUTES lpEventAttributes,
  194.     IN BOOL bManualReset,
  195.     IN BOOL bInitialState,
  196.     IN LPCWSTR lpName
  197.     )
  198. {
  199.     CMbcsBuffer mbcsName;
  200.     if (!mbcsName.FromUnicode(lpName))
  201.         return NULL;
  202.  
  203.     return ::CreateEventA(lpEventAttributes, bManualReset, bInitialState, mbcsName);
  204. }
  205.  
  206. HANDLE WINAPI
  207. CreateFileMappingW(
  208.     IN HANDLE hFile,
  209.     IN LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
  210.     IN DWORD flProtect,
  211.     IN DWORD dwMaximumSizeHigh,
  212.     IN DWORD dwMaximumSizeLow,
  213.     IN LPCWSTR lpName
  214.     )
  215. {
  216.     CMbcsBuffer mbcsName;
  217.     if (!mbcsName.FromUnicode(lpName))
  218.         return NULL;
  219.  
  220.     return ::CreateFileMappingA(hFile, lpFileMappingAttributes, flProtect,
  221.         dwMaximumSizeHigh, dwMaximumSizeLow, mbcsName);
  222. }
  223. #endif
  224. extern "C" HANDLE WINAPI
  225. zCreateFileW(
  226.     IN LPCWSTR lpFileName,
  227.     IN DWORD dwDesiredAccess,
  228.     IN DWORD dwShareMode,
  229.     IN LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  230.     IN DWORD dwCreationDisposition,
  231.     IN DWORD dwFlagsAndAttributes,
  232.     IN HANDLE hTemplateFile
  233.     )
  234. {
  235.     CMbcsBuffer mbcsFileName;
  236.     if (!mbcsFileName.FromUnicode(lpFileName))
  237.         return INVALID_HANDLE_VALUE;
  238.  
  239.     return ::CreateFileA(mbcsFileName, dwDesiredAccess, dwShareMode,
  240.         lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
  241.         hTemplateFile);
  242. }
  243. #if 0
  244. HANDLE WINAPI
  245. CreateMailslotW(
  246.     IN LPCWSTR lpName,
  247.     IN DWORD nMaxMessageSize,
  248.     IN DWORD lReadTimeout,
  249.     IN LPSECURITY_ATTRIBUTES lpSecurityAttributes
  250.     )
  251. {
  252.     CMbcsBuffer mbcsName;
  253.     if (!mbcsName.FromUnicode(lpName))
  254.         return INVALID_HANDLE_VALUE;
  255.  
  256.     return ::CreateMailslotA(mbcsName, nMaxMessageSize, lReadTimeout, lpSecurityAttributes);
  257. }
  258.  
  259. HANDLE WINAPI
  260. CreateMutexW(
  261.     IN LPSECURITY_ATTRIBUTES lpMutexAttributes,
  262.     IN BOOL bInitialOwner,
  263.     IN LPCWSTR lpName
  264.     )
  265. {
  266.     CMbcsBuffer mbcsName;
  267.     if (!mbcsName.FromUnicode(lpName))
  268.         return NULL;
  269.  
  270.     return ::CreateMutexA(lpMutexAttributes, bInitialOwner, mbcsName);
  271. }
  272.  
  273. // CreateNamedPipeW
  274.  
  275. BOOL WINAPI
  276. CreateProcessW(
  277.     IN LPCWSTR lpApplicationName,
  278.     IN LPWSTR lpCommandLine,
  279.     IN LPSECURITY_ATTRIBUTES lpProcessAttributes,
  280.     IN LPSECURITY_ATTRIBUTES lpThreadAttributes,
  281.     IN BOOL bInheritHandles,
  282.     IN DWORD dwCreationFlags,
  283.     IN LPVOID lpEnvironment,
  284.     IN LPCWSTR lpCurrentDirectory,
  285.     IN LPSTARTUPINFOW lpStartupInfo,
  286.     OUT LPPROCESS_INFORMATION lpProcessInformation
  287.     )
  288. {
  289.     CMbcsBuffer mbcsApplicationName;
  290.     if (!mbcsApplicationName.FromUnicode(lpApplicationName))
  291.         return FALSE;
  292.  
  293.     CMbcsBuffer mbcsCommandLine;
  294.     if (!mbcsCommandLine.FromUnicode(lpCommandLine))
  295.         return FALSE;
  296.  
  297.     CMbcsBuffer mbcsCurrentDirectory;
  298.     if (!mbcsCurrentDirectory.FromUnicode(lpCurrentDirectory))
  299.         return FALSE;
  300.  
  301.     STARTUPINFOA startupInfoA;
  302.     ::ZeroMemory(&startupInfoA, sizeof(startupInfoA));
  303.     startupInfoA.cb              = sizeof(startupInfoA);
  304.     startupInfoA.dwX             = lpStartupInfo->dwX;
  305.     startupInfoA.dwY             = lpStartupInfo->dwY;
  306.     startupInfoA.dwXSize         = lpStartupInfo->dwXSize;
  307.     startupInfoA.dwYSize         = lpStartupInfo->dwYSize;
  308.     startupInfoA.dwXCountChars   = lpStartupInfo->dwXCountChars;
  309.     startupInfoA.dwYCountChars   = lpStartupInfo->dwYCountChars;
  310.     startupInfoA.dwFillAttribute = lpStartupInfo->dwFillAttribute;
  311.     startupInfoA.dwFlags         = lpStartupInfo->dwFlags;
  312.     startupInfoA.wShowWindow     = lpStartupInfo->wShowWindow;
  313.     startupInfoA.hStdInput       = lpStartupInfo->hStdInput;
  314.     startupInfoA.hStdOutput      = lpStartupInfo->hStdOutput;
  315.     startupInfoA.hStdError       = lpStartupInfo->hStdError;
  316.  
  317.     CMbcsBuffer mbcsDesktop;
  318.     if (!mbcsDesktop.FromUnicode(lpStartupInfo->lpDesktop))
  319.         return FALSE;
  320.     startupInfoA.lpDesktop = mbcsDesktop;
  321.  
  322.     CMbcsBuffer mbcsTitle;
  323.     if (!mbcsTitle.FromUnicode(lpStartupInfo->lpTitle))
  324.         return FALSE;
  325.     startupInfoA.lpTitle = mbcsTitle;
  326.  
  327.     return ::CreateProcessA(mbcsApplicationName, mbcsCommandLine,
  328.         lpProcessAttributes, lpThreadAttributes, bInheritHandles,
  329.         dwCreationFlags, lpEnvironment, mbcsCurrentDirectory,
  330.         &startupInfoA, lpProcessInformation);
  331. }
  332.  
  333. HANDLE WINAPI
  334. CreateSemaphoreW(
  335.     IN LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
  336.     IN LONG lInitialCount,
  337.     IN LONG lMaximumCount,
  338.     IN LPCWSTR lpName
  339.     )
  340. {
  341.     CMbcsBuffer mbcsName;
  342.     if (!mbcsName.FromUnicode(lpName))
  343.         return NULL;
  344.  
  345.     return ::CreateSemaphoreA(lpSemaphoreAttributes, lInitialCount, lMaximumCount, mbcsName);
  346. }
  347.  
  348. typedef HANDLE (WINAPI *fpCreateWaitableTimerA)(
  349.     IN LPSECURITY_ATTRIBUTES lpTimerAttributes,
  350.     IN BOOL bManualReset,
  351.     IN LPCSTR lpTimerName
  352.     );
  353.  
  354. HANDLE WINAPI
  355. CreateWaitableTimerW(
  356.     IN LPSECURITY_ATTRIBUTES lpTimerAttributes,
  357.     IN BOOL bManualReset,
  358.     IN LPCWSTR lpTimerName
  359.     )
  360. {
  361.     static fpCreateWaitableTimerA pCreateWaitableTimerA =
  362.         (fpCreateWaitableTimerA) ::GetProcAddress(
  363.             ::GetModuleHandleA("kernel32.dll"), "CreateWaitableTimerA");
  364.     if (!pCreateWaitableTimerA) {
  365.         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  366.         return NULL;
  367.     }
  368.  
  369.     CMbcsBuffer mbcsTimerName;
  370.     if (!mbcsTimerName.FromUnicode(lpTimerName))
  371.         return NULL;
  372.  
  373.     return pCreateWaitableTimerA(lpTimerAttributes, bManualReset, mbcsTimerName);
  374. }
  375. #endif
  376. extern "C" BOOL WINAPI
  377. zDeleteFileW(
  378.     IN LPCWSTR lpFileName
  379.     )
  380. {
  381.     CMbcsBuffer mbcsFileName;
  382.     if (!mbcsFileName.FromUnicode(lpFileName))
  383.         return FALSE;
  384.  
  385.     return ::DeleteFileA(mbcsFileName);
  386. }
  387.  
  388. // EndUpdateResourceA
  389. // EndUpdateResourceW
  390. // EnumCalendarInfoExW
  391. // EnumCalendarInfoW
  392. // EnumDateFormatsExW
  393. // EnumDateFormatsW
  394. // EnumSystemCodePagesW
  395. // EnumSystemLocalesW
  396. // EnumTimeFormatsW
  397. #if 0
  398. DWORD WINAPI
  399. ExpandEnvironmentStringsW(
  400.     IN LPCWSTR lpSrc,
  401.     OUT LPWSTR lpDst,
  402.     IN DWORD nSize
  403.     )
  404. {
  405.     CMbcsBuffer mbcsSrc;
  406.     if (!mbcsSrc.FromUnicode(lpSrc))
  407.         return FALSE;
  408.  
  409.     DWORD dwResult = 0;
  410.     CMbcsBuffer mbcsDst;
  411.     do {
  412.         if (dwResult > (DWORD) mbcsDst.BufferSize()) {
  413.             if (!mbcsDst.SetCapacity((int) dwResult))
  414.                 return 0;
  415.         }
  416.  
  417.         dwResult = ::ExpandEnvironmentStringsA(mbcsSrc, mbcsDst, (DWORD) mbcsDst.BufferSize());
  418.         if (!dwResult)
  419.             return 0;
  420.     }
  421.     while (dwResult > (DWORD) mbcsDst.BufferSize());
  422.     int nDstLen = ::lstrlenA(mbcsDst);
  423.  
  424.     // ensure the supplied buffer is big enough
  425.     int nRequiredSize = ::MultiByteToWideChar(CP_ACP, 0, mbcsDst, nDstLen + 1, 0, 0);
  426.     if (nSize < (DWORD) nRequiredSize)
  427.         return (DWORD) nRequiredSize;
  428.  
  429.     ::MultiByteToWideChar(CP_ACP, 0, mbcsDst, nDstLen + 1, lpDst, nSize);
  430.     return nRequiredSize; // include the NULL
  431. }
  432.  
  433. VOID WINAPI
  434. FatalAppExitW(
  435.     IN UINT uAction,
  436.     IN LPCWSTR lpMessageText
  437.     )
  438. {
  439.     CMbcsBuffer mbcsMessageText;
  440.     mbcsMessageText.FromUnicode(lpMessageText);
  441.     ::FatalAppExit(uAction, mbcsMessageText);
  442. }
  443.  
  444. // FillConsoleOutputCharacterW
  445.  
  446. ATOM WINAPI
  447. FindAtomW(
  448.     IN LPCWSTR lpString
  449.     )
  450. {
  451.     CMbcsBuffer mbcsString;
  452.     if (!mbcsString.FromUnicode(lpString))
  453.         return 0;
  454.  
  455.     return ::FindAtomA(mbcsString);
  456. }
  457.  
  458. HANDLE WINAPI
  459. FindFirstChangeNotificationW(
  460.     IN LPCWSTR lpPathName,
  461.     IN BOOL bWatchSubtree,
  462.     IN DWORD dwNotifyFilter
  463.     )
  464. {
  465.     CMbcsBuffer mbcsPathName;
  466.     if (!mbcsPathName.FromUnicode(lpPathName))
  467.         return INVALID_HANDLE_VALUE;
  468.  
  469.     return ::FindFirstChangeNotificationA(mbcsPathName, bWatchSubtree, dwNotifyFilter);
  470. }
  471. #endif
  472. static void
  473. CopyFindDataAtoW(
  474.     LPWIN32_FIND_DATAA lpFindDataA,
  475.     LPWIN32_FIND_DATAW lpFindDataW
  476.     )
  477. {
  478.     lpFindDataW->dwFileAttributes = lpFindDataA->dwFileAttributes;
  479.     lpFindDataW->ftCreationTime   = lpFindDataA->ftCreationTime;
  480.     lpFindDataW->ftLastAccessTime = lpFindDataA->ftLastAccessTime;
  481.     lpFindDataW->ftLastWriteTime  = lpFindDataA->ftLastWriteTime;
  482.     lpFindDataW->nFileSizeHigh    = lpFindDataA->nFileSizeHigh;
  483.     lpFindDataW->nFileSizeLow     = lpFindDataA->nFileSizeLow;
  484.     lpFindDataW->dwReserved0      = lpFindDataA->dwReserved0;
  485.     lpFindDataW->dwReserved1      = lpFindDataA->dwReserved1;
  486.    
  487.     ::MultiByteToWideChar(CP_ACP, 0, lpFindDataA->cFileName, -1,
  488.         lpFindDataW->cFileName, MAX_PATH);
  489.  
  490.     ::MultiByteToWideChar(CP_ACP, 0, lpFindDataA->cAlternateFileName, -1,
  491.         lpFindDataW->cAlternateFileName,
  492.         ARRAY_SIZE(lpFindDataW->cAlternateFileName));
  493. }
  494.  
  495. extern "C" HANDLE WINAPI
  496. zFindFirstFileW(
  497.     IN LPCWSTR lpFileName,
  498.     OUT LPWIN32_FIND_DATAW lpFindFileData
  499.     )
  500. {
  501.     CMbcsBuffer mbcsFileName;
  502.     if (!mbcsFileName.FromUnicode(lpFileName))
  503.         return INVALID_HANDLE_VALUE;
  504.  
  505.     WIN32_FIND_DATAA findDataA;
  506.     HANDLE hFile = ::FindFirstFileA(mbcsFileName, &findDataA);
  507.     if (hFile == INVALID_HANDLE_VALUE)
  508.         return INVALID_HANDLE_VALUE;
  509.  
  510.     CopyFindDataAtoW(&findDataA, lpFindFileData);
  511.     return hFile;
  512. }
  513.  
  514. extern "C" BOOL WINAPI
  515. zFindNextFileW(
  516.     IN HANDLE hFindFile,
  517.     OUT LPWIN32_FIND_DATAW lpFindFileData
  518.     )
  519. {
  520.     WIN32_FIND_DATAA findDataA;
  521.     BOOL bSuccess = ::FindNextFileA(hFindFile, &findDataA);
  522.     if (bSuccess)
  523.         CopyFindDataAtoW(&findDataA, lpFindFileData);
  524.     return bSuccess;
  525. }
  526. #if 0
  527. HRSRC WINAPI
  528. FindResourceExW(
  529.     IN HMODULE hModule,
  530.     IN LPCWSTR lpType,
  531.     IN LPCWSTR lpName,
  532.     IN WORD    wLanguage
  533.     )
  534. {
  535.     LPCSTR lpTypeA = (LPCSTR) lpType;
  536.     CMbcsBuffer mbcsType;
  537.     if (!IS_INTRESOURCE(lpType)) {
  538.         if (!mbcsType.FromUnicode(lpType))
  539.             return NULL;
  540.         lpTypeA = mbcsType;
  541.     }
  542.  
  543.     LPCSTR lpNameA = (LPCSTR) lpName;
  544.     CMbcsBuffer mbcsName;
  545.     if (!IS_INTRESOURCE(lpName)) {
  546.         if (!mbcsName.FromUnicode(lpName))
  547.             return NULL;
  548.         lpNameA = mbcsName;
  549.     }
  550.  
  551.     return ::FindResourceExA(hModule, lpTypeA, lpNameA, wLanguage);
  552. }
  553. #endif
  554. extern "C" HRSRC WINAPI
  555. zFindResourceW(
  556.     IN HMODULE hModule,
  557.     IN LPCWSTR lpName,
  558.     IN LPCWSTR lpType
  559.     )
  560. {
  561.     LPCSTR lpTypeA = (LPCSTR) lpType;
  562.     CMbcsBuffer mbcsType;
  563.     if (!IS_INTRESOURCE(lpType)) {
  564.         if (!mbcsType.FromUnicode(lpType))
  565.             return NULL;
  566.         lpTypeA = mbcsType;
  567.     }
  568.  
  569.     LPCSTR lpNameA = (LPCSTR) lpName;
  570.     CMbcsBuffer mbcsName;
  571.     if (!IS_INTRESOURCE(lpName)) {
  572.         if (!mbcsName.FromUnicode(lpName))
  573.             return NULL;
  574.         lpNameA = mbcsName;
  575.     }
  576.  
  577.     return ::FindResourceA(hModule, lpTypeA, lpNameA);
  578. }
  579. /*
  580. // FormatMessageW
  581. DWORD WINAPI
  582. zFormatMessage(
  583.   IN  LPCVOID lpSource,
  584.   IN  DWORD dwMessageId,
  585.   IN  DWORD dwLanguageId,
  586.   OUT LPTSTR lpBuffer,
  587.   IN  DWORD nSize,
  588.   IN  va_list *Arguments
  589. )
  590. {
  591.  
  592. } */
  593.  
  594. extern "C" BOOL WINAPI
  595. zFreeEnvironmentStringsW(
  596.     IN LPWSTR lpStrings
  597.     )
  598. {
  599.     if (lpStrings)
  600.         ::free(lpStrings);
  601.     return TRUE;
  602. }
  603.  
  604. #if 0
  605. UINT WINAPI
  606. GetAtomNameW(
  607.     IN ATOM nAtom,
  608.     OUT LPWSTR lpBuffer,
  609.     IN int nSize
  610.     )
  611. {
  612.     CMbcsBuffer mbcsBuffer;
  613.     UINT uiLen = ::GetAtomNameA(nAtom, mbcsBuffer, mbcsBuffer.BufferSize());
  614.     if (!uiLen)
  615.         return 0;
  616.  
  617.     int nLen = ::MultiByteToWideChar(CP_ACP, 0, mbcsBuffer, uiLen + 1, lpBuffer, nSize);
  618.     if (!nLen) {
  619.         SetLastError(ERROR_INSUFFICIENT_BUFFER);
  620.         return 0;
  621.     }
  622.  
  623.     return (UINT) (nLen - 1);
  624. }
  625. //#endif
  626. //TODO: MSLU adds support for CP_UTF7 and CP_UTF8
  627. BOOL WINAPI
  628. OCOW_GetCPInfo(
  629.     IN UINT       CodePage,
  630.     OUT LPCPINFO  lpCPInfo
  631.     )
  632. {
  633.     return ::GetCPInfo(CodePage, lpCPInfo);
  634. }
  635. //#if 0
  636. //TODO: MSLU adds support for CP_UTF7 and CP_UTF8
  637. BOOL WINAPI
  638. GetCPInfoExW(
  639.     IN UINT          CodePage,
  640.     IN DWORD         dwFlags,
  641.     OUT LPCPINFOEXW  lpCPInfoEx
  642.     )
  643. {
  644.     CPINFOEXA cpInfoA;
  645.     BOOL bSuccess = ::GetCPInfoExA(CodePage, dwFlags, &cpInfoA);
  646.     if (!bSuccess)
  647.         return FALSE;
  648.  
  649.     lpCPInfoEx->CodePage = cpInfoA.CodePage;
  650.     ::CopyMemory(lpCPInfoEx->DefaultChar, cpInfoA.DefaultChar, MAX_DEFAULTCHAR);
  651.     ::CopyMemory(lpCPInfoEx->LeadByte, cpInfoA.LeadByte, MAX_LEADBYTES);
  652.     lpCPInfoEx->MaxCharSize = cpInfoA.MaxCharSize;
  653.     lpCPInfoEx->UnicodeDefaultChar = cpInfoA.UnicodeDefaultChar;
  654.     ::MultiByteToWideChar(CP_ACP, 0, cpInfoA.CodePageName, -1, lpCPInfoEx->CodePageName, MAX_PATH);
  655.  
  656.     return TRUE;
  657. }
  658.  
  659. // GetCalendarInfoW
  660.  
  661. BOOL WINAPI
  662. GetComputerNameW(
  663.     OUT LPWSTR lpBuffer,
  664.     IN OUT LPDWORD lpnSize
  665.     )
  666. {
  667.     CMbcsBuffer mbcsBuffer;
  668.     DWORD dwLen = mbcsBuffer.BufferSize();
  669.     if (!::GetComputerNameA(mbcsBuffer, &dwLen))
  670.         return FALSE;
  671.  
  672.     int nRequiredLen = ::MultiByteToWideChar(CP_ACP, 0, mbcsBuffer, (int) dwLen + 1, 0, 0);
  673.     if (*lpnSize < (DWORD) nRequiredLen) {
  674.         *lpnSize = (DWORD) (nRequiredLen - 1);
  675.         SetLastError(ERROR_MORE_DATA);
  676.         return FALSE;
  677.     }
  678.  
  679.     ::MultiByteToWideChar(CP_ACP, 0, mbcsBuffer, (int) dwLen + 1, lpBuffer, *lpnSize);
  680.     *lpnSize = (DWORD) (nRequiredLen - 1);
  681.     return TRUE;
  682. }
  683. #endif
  684. // GetConsoleTitleW
  685. // GetCurrencyFormatW
  686.  
  687. extern "C" DWORD WINAPI
  688. zGetCurrentDirectoryW(
  689.     IN DWORD uSize,
  690.     OUT LPWSTR lpBuffer
  691.     )
  692. {
  693.     DWORD dwResult = 0;
  694.     CMbcsBuffer mbcsBuffer;
  695.     do {
  696.         if (dwResult > (DWORD) mbcsBuffer.BufferSize()) {
  697.             if (!mbcsBuffer.SetCapacity((int) dwResult))
  698.                 return 0;
  699.         }
  700.  
  701.         dwResult = ::GetCurrentDirectoryA((DWORD) mbcsBuffer.BufferSize(), mbcsBuffer);
  702.         if (!dwResult)
  703.             return 0;
  704.     }
  705.     while (dwResult > (DWORD) mbcsBuffer.BufferSize());
  706.     int nBufferLen = ::lstrlenA(mbcsBuffer);
  707.  
  708.     // ensure the supplied buffer is big enough
  709.     int nRequiredSize = ::MultiByteToWideChar(CP_ACP, 0, mbcsBuffer, nBufferLen + 1, 0, 0);
  710.     if (uSize < (DWORD) nRequiredSize)
  711.         return (DWORD) nRequiredSize;
  712.  
  713.     ::MultiByteToWideChar(CP_ACP, 0, mbcsBuffer, nBufferLen + 1, lpBuffer, uSize);
  714.     return nRequiredSize - 1; // do not include the NULL
  715. }
  716.  
  717. // GetDateFormatW
  718. // GetDefaultCommConfigW
  719. #if 0
  720. typedef BOOL (WINAPI *fpGetDiskFreeSpaceExA)(
  721.     IN LPCSTR lpDirectoryName,
  722.     OUT PULARGE_INTEGER lpFreeBytesAvailableToCaller,
  723.     OUT PULARGE_INTEGER lpTotalNumberOfBytes,
  724.     OUT PULARGE_INTEGER lpTotalNumberOfFreeBytes
  725.     );
  726.  
  727. BOOL WINAPI
  728. GetDiskFreeSpaceExW(
  729.     IN LPCWSTR lpDirectoryName,
  730.     OUT PULARGE_INTEGER lpFreeBytesAvailableToCaller,
  731.     OUT PULARGE_INTEGER lpTotalNumberOfBytes,
  732.     OUT PULARGE_INTEGER lpTotalNumberOfFreeBytes
  733.     )
  734. {
  735.     // dynamically loaded
  736.     static fpGetDiskFreeSpaceExA pGetDiskFreeSpaceExA = 0;
  737.     if (!pGetDiskFreeSpaceExA) {
  738.         pGetDiskFreeSpaceExA = (fpGetDiskFreeSpaceExA)
  739.             ::GetProcAddress(::GetModuleHandleA("kernel32.dll"), "GetDiskFreeSpaceExA");
  740.         if (!pGetDiskFreeSpaceExA) {
  741.             SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  742.             return FALSE;
  743.         }
  744.     }
  745.  
  746.     CMbcsBuffer mbcsDirectoryName;
  747.     if (!mbcsDirectoryName.FromUnicode(lpDirectoryName))
  748.         return FALSE;
  749.  
  750.     return pGetDiskFreeSpaceExA(mbcsDirectoryName, lpFreeBytesAvailableToCaller,
  751.         lpTotalNumberOfBytes, lpTotalNumberOfFreeBytes);
  752. }
  753.  
  754. BOOL WINAPI
  755. GetDiskFreeSpaceW(
  756.     IN LPCWSTR lpRootPathName,
  757.     OUT LPDWORD lpSectorsPerCluster,
  758.     OUT LPDWORD lpBytesPerSector,
  759.     OUT LPDWORD lpNumberOfFreeClusters,
  760.     OUT LPDWORD lpTotalNumberOfClusters
  761.     )
  762. {
  763.     CMbcsBuffer mbcsRootPathName;
  764.     if (!mbcsRootPathName.FromUnicode(lpRootPathName))
  765.         return FALSE;
  766.  
  767.     return ::GetDiskFreeSpaceA(mbcsRootPathName, lpSectorsPerCluster,
  768.         lpBytesPerSector, lpNumberOfFreeClusters, lpTotalNumberOfClusters);
  769. }
  770. #endif
  771. extern "C" UINT WINAPI
  772. zGetDriveTypeW(
  773.     IN LPCWSTR lpRootPathName
  774.     )
  775. {
  776.     CMbcsBuffer mbcsRootPathName;
  777.     if (!mbcsRootPathName.FromUnicode(lpRootPathName))
  778.         return DRIVE_UNKNOWN;
  779.  
  780.     return ::GetDriveTypeA(mbcsRootPathName);
  781. }
  782.  
  783. extern LPSTR WINAPI GetEnvironmentStringsA(VOID);
  784. extern "C" LPWSTR WINAPI
  785. GetEnvironmentStringsW(
  786.     VOID
  787.     )
  788. {
  789.     typedef LPWSTR (WINAPI* LPFNGETENVSTRINGS)(void);
  790. //    typedef LPWSTR (__stdcall* LPFNGETENVSTRINGS)(void);
  791.  
  792.     HMODULE kernel32 = LoadLibraryA("kernel32.dll");
  793.     if (!kernel32)
  794.         return 0;
  795.     LPFNGETENVSTRINGS pf = (LPFNGETENVSTRINGS)GetProcAddress(kernel32, "GetEnvironmentStringsW");
  796.     if (pf)
  797.     {
  798.         LPWSTR ret = pf();
  799.         FreeLibrary(kernel32);
  800.         return ret;
  801.     }
  802.     FreeLibrary(kernel32);
  803. #ifdef GetEnvironmentStrings
  804. #undef GetEnvironmentStrings
  805. #endif
  806.     LPSTR pStringsA = ::GetEnvironmentStrings();//A();
  807.     if (!pStringsA)
  808.         return 0;
  809.  
  810.     int nTotalLen = 0;
  811.     int nLen = ::lstrlenA(pStringsA);
  812.     while (nLen > 0) {
  813.         nTotalLen += nLen + 1;
  814.         nLen = ::lstrlenA(pStringsA + nTotalLen);
  815.     }
  816.     ++nTotalLen;
  817.  
  818.     int nRequiredLen = ::MultiByteToWideChar(CP_ACP, 0, pStringsA, nTotalLen, 0, 0);
  819.     if (nRequiredLen < 1) {
  820.         ::FreeEnvironmentStringsA(pStringsA);
  821.         return 0;
  822.     }
  823.  
  824.     LPWSTR pStringsW = (LPWSTR) ::malloc(nRequiredLen * sizeof(wchar_t));
  825.     if (!pStringsW) {
  826.         ::FreeEnvironmentStringsA(pStringsA);
  827.         return 0;
  828.     }
  829.  
  830.     ::MultiByteToWideChar(CP_ACP, 0, pStringsA, nTotalLen, pStringsW, nRequiredLen);
  831.     ::FreeEnvironmentStringsA(pStringsA);
  832.  
  833.     return pStringsW;
  834. }
  835.  
  836. #if 0
  837. DWORD WINAPI
  838. GetEnvironmentVariableW(
  839.     IN LPCWSTR lpName,
  840.     OUT LPWSTR lpBuffer,
  841.     IN DWORD nSize
  842.     )
  843. {
  844.     CMbcsBuffer mbcsName;
  845.     if (!mbcsName.FromUnicode(lpName))
  846.         return 0;
  847.  
  848.     DWORD dwResult = 0;
  849.     CMbcsBuffer mbcsBuffer;
  850.     do {
  851.         if (dwResult > (DWORD) mbcsBuffer.BufferSize()) {
  852.             if (!mbcsBuffer.SetCapacity((int) dwResult))
  853.                 return 0;
  854.         }
  855.  
  856.         dwResult = ::GetEnvironmentVariableA(mbcsName, mbcsBuffer, (DWORD) mbcsBuffer.BufferSize());
  857.         if (!dwResult)
  858.             return 0;
  859.     }
  860.     while (dwResult > (DWORD) mbcsBuffer.BufferSize());
  861.     int nBufferLen = ::lstrlenA(mbcsBuffer);
  862.  
  863.     // ensure the supplied buffer is big enough
  864.     int nRequiredSize = ::MultiByteToWideChar(CP_ACP, 0, mbcsBuffer, nBufferLen + 1, 0, 0);
  865.     if (nSize < (DWORD) nRequiredSize)
  866.         return (DWORD) nRequiredSize;
  867.  
  868.     ::MultiByteToWideChar(CP_ACP, 0, mbcsBuffer, nBufferLen + 1, lpBuffer, nSize);
  869.     return nRequiredSize - 1; // don't include NULL
  870. }
  871. #endif
  872. // GetFileAttributesExW
  873.  
  874. extern "C" DWORD WINAPI
  875. zGetFileAttributesW(
  876.     IN LPCWSTR lpFileName
  877.     )
  878. {
  879.     CMbcsBuffer mbcsFileName;
  880.     if (!mbcsFileName.FromUnicode(lpFileName))
  881.         return INVALID_FILE_ATTRIBUTES;
  882.  
  883.     return ::GetFileAttributesA(mbcsFileName);
  884. }
  885.  
  886. extern "C" DWORD WINAPI
  887. zGetFullPathNameW(
  888.     IN LPCWSTR lpFileName,
  889.     IN DWORD uSize,
  890.     OUT LPWSTR lpBuffer,
  891.     OUT LPWSTR *lpFilePart
  892.     )
  893. {
  894.     CMbcsBuffer mbcsFileName;
  895.     if (!mbcsFileName.FromUnicode(lpFileName))
  896.         return 0;
  897.  
  898.     DWORD dwResult = 0;
  899.     CMbcsBuffer mbcsBuffer;
  900.     do {
  901.         if (dwResult > (DWORD) mbcsBuffer.BufferSize()) {
  902.             if (!mbcsBuffer.SetCapacity((int) dwResult))
  903.                 return 0;
  904.         }
  905.  
  906.         char * pszFilePart;
  907.         dwResult = ::GetFullPathNameA(mbcsFileName, (DWORD) mbcsBuffer.BufferSize(), mbcsBuffer, &pszFilePart);
  908.         if (!dwResult)
  909.             return 0;
  910.     }
  911.     while (dwResult > (DWORD) mbcsBuffer.BufferSize());
  912.     int nBufferLen = ::lstrlenA(mbcsBuffer);
  913.  
  914.     // ensure the supplied buffer is big enough
  915.     int nRequiredSize = ::MultiByteToWideChar(CP_ACP, 0, mbcsBuffer, nBufferLen + 1, 0, 0);
  916.     if (uSize < (DWORD) nRequiredSize)
  917.         return (DWORD) nRequiredSize;
  918.  
  919.     ::MultiByteToWideChar(CP_ACP, 0, mbcsBuffer, nBufferLen + 1, lpBuffer, uSize);
  920.  
  921.     // set the file part pointer to the beginning of the file, we know that
  922.     // there must be a slash in the path somewhere, so this loop won't run
  923.     // off the beginning of the string
  924.     if (lpFilePart) {
  925.         wchar_t * pFilePart = lpBuffer + nRequiredSize - 1;
  926.         while (*pFilePart != L'\\')
  927.             --pFilePart;
  928.         *lpFilePart = pFilePart;
  929.     }
  930.  
  931.     return nRequiredSize - 1; // do not include the NULL
  932. }
  933.  
  934. // GetLocaleInfoW
  935. #if 0
  936. DWORD WINAPI
  937. GetLogicalDriveStringsW(
  938.     IN DWORD nBufferLength,
  939.     OUT LPWSTR lpBuffer
  940.     )
  941. {
  942.     CMbcsBuffer mbcsDriveStrings;
  943.     if (!mbcsDriveStrings.SetCapacity(nBufferLength))
  944.         return 0;
  945.  
  946.     int len = ::GetLogicalDriveStringsA(mbcsDriveStrings.BufferSize(), mbcsDriveStrings);
  947.     if (len > 0 && len < mbcsDriveStrings.BufferSize()) {
  948.         // include terminating null character by using len + 1
  949.         int nResult = ::MultiByteToWideChar(CP_ACP, 0, mbcsDriveStrings,
  950.             len + 1, lpBuffer, nBufferLength);
  951.         if (nResult == 0) {
  952.             if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
  953.                 len = ::MultiByteToWideChar(CP_ACP, 0, mbcsDriveStrings, len + 1, 0, 0);
  954.             else
  955.                 len = 0;
  956.         }
  957.         else {
  958.             len = nResult - 1; // don't include the NULL
  959.         }
  960.     }
  961.  
  962.     return len;
  963. }
  964.  
  965. DWORD WINAPI
  966. GetLongPathNameW(
  967.     IN LPCWSTR  lpszShortPath,
  968.     OUT LPWSTR  lpszLongPath,
  969.     IN DWORD    cchBuffer
  970.     )
  971. {
  972.     CMbcsBuffer mbcsShortPath;
  973.     if (!mbcsShortPath.FromUnicode(lpszShortPath))
  974.         return 0;
  975.  
  976.     DWORD dwResult = 0;
  977.     CMbcsBuffer mbcsLongPath;
  978.     do {
  979.         if (dwResult > (DWORD) mbcsLongPath.BufferSize()) {
  980.             if (!mbcsLongPath.SetCapacity((int) dwResult))
  981.                 return 0;
  982.         }
  983.  
  984.         dwResult = ::GetLongPathNameA(mbcsShortPath, mbcsLongPath, (DWORD) mbcsLongPath.BufferSize());
  985.         if (!dwResult)
  986.             return 0;
  987.     }
  988.     while (dwResult > (DWORD) mbcsLongPath.BufferSize());
  989.     int nLongPathLen = ::lstrlenA(mbcsLongPath);
  990.  
  991.     // ensure the supplied buffer is big enough
  992.     int nRequiredSize = ::MultiByteToWideChar(CP_ACP, 0, mbcsLongPath, nLongPathLen + 1, 0, 0);
  993.     if (cchBuffer < (DWORD) nRequiredSize)
  994.         return (DWORD) nRequiredSize;
  995.  
  996.     ::MultiByteToWideChar(CP_ACP, 0, mbcsLongPath, nLongPathLen + 1, lpszLongPath, cchBuffer);
  997.     return nRequiredSize - 1; // do not include the NULL
  998. }
  999.  
  1000. #endif
  1001. extern "C" DWORD WINAPI
  1002. zGetModuleFileNameW(
  1003.     IN HMODULE hModule,
  1004.     OUT LPWSTR lpFilename,
  1005.     IN DWORD nSize
  1006.     )
  1007. {
  1008.     CMbcsBuffer mbcsFilename;
  1009.     if (!mbcsFilename.SetCapacity(nSize))
  1010.         return 0;
  1011.  
  1012.     //TODO: does the return value include the NULL char or not??
  1013.     if (!::GetModuleFileNameA(hModule, mbcsFilename, mbcsFilename.BufferSize()))
  1014.         return 0;
  1015.  
  1016.     return (DWORD) ::MultiByteToWideChar(CP_ACP, 0, mbcsFilename, -1, lpFilename, nSize);
  1017. }
  1018. extern "C" HMODULE WINAPI
  1019. zGetModuleHandleW(
  1020.     IN LPCWSTR lpModuleName
  1021.     )
  1022. {
  1023.     CMbcsBuffer mbcsModuleName;
  1024.     if (!mbcsModuleName.FromUnicode(lpModuleName))
  1025.         return NULL;
  1026.  
  1027.     return ::GetModuleHandleA(mbcsModuleName);
  1028. }
  1029.  
  1030. // GetNamedPipeHandleStateW
  1031. // GetNumberFormatW
  1032. // GetPrivateProfileIntW
  1033. // GetPrivateProfileSectionNamesW
  1034. // GetPrivateProfileSectionW
  1035. // GetPrivateProfileStringW
  1036. // GetPrivateProfileStructW
  1037. #if 0
  1038. typedef struct _MsluExport {
  1039.     const char * dllName;
  1040.     const char * exportName;
  1041. } MsluExport;
  1042.  
  1043. static int __cdecl
  1044. OCOW_Compare(
  1045.     const void * first,
  1046.     const void * second
  1047.     )
  1048. {
  1049.     const MsluExport * term1 = reinterpret_cast<const MsluExport*>(first);
  1050.     const MsluExport * term2 = reinterpret_cast<const MsluExport*>(second);
  1051.     int nResult = ::strcmp(term1->dllName, term2->dllName);
  1052.     if (nResult == 0)
  1053.         nResult = ::strcmp(term1->exportName, term2->exportName);
  1054.     return nResult;
  1055. }
  1056.  
  1057. FARPROC WINAPI
  1058. OCOW_GetProcAddress(
  1059.     IN HMODULE hModule,
  1060.     IN LPCSTR lpProcName
  1061.     )
  1062. {
  1063.     // we need to catch any request for a known wrapped MSLU function
  1064.     // and redirect it to a GetProcAddress to this DLL. This list is generated
  1065.     // from the libunicows file symbols.txt using manual regexp replacement to
  1066.     // create the proper format and sorting so that bsearch works correctly.
  1067.     // The contents of the OCOW.def section for msvcrt.dll has been added manually.
  1068.  
  1069.     static const MsluExport rgCheckedExports[] = {
  1070.         { "advapi32.dll", "CryptAcquireContextW" },
  1071.         { "advapi32.dll", "CryptEnumProvidersW" },
  1072.         { "advapi32.dll", "CryptEnumProviderTypesW" },
  1073.         { "advapi32.dll", "CryptGetDefaultProviderW" },
  1074.         { "advapi32.dll", "CryptSetProviderExW" },
  1075.         { "advapi32.dll", "CryptSetProviderW" },
  1076.         { "advapi32.dll", "CryptSignHashW" },
  1077.         { "advapi32.dll", "CryptVerifySignatureW" },
  1078.         { "advapi32.dll", "GetCurrentHwProfileW" },
  1079.         { "advapi32.dll", "GetUserNameW" },
  1080.         { "advapi32.dll", "IsTextUnicode" },
  1081.         { "advapi32.dll", "RegConnectRegistryW" },
  1082.         { "advapi32.dll", "RegCreateKeyExW" },
  1083.         { "advapi32.dll", "RegCreateKeyW" },
  1084.         { "advapi32.dll", "RegDeleteKeyW" },
  1085.         { "advapi32.dll", "RegDeleteValueW" },
  1086.         { "advapi32.dll", "RegEnumKeyExW" },
  1087.         { "advapi32.dll", "RegEnumKeyW" },
  1088.         { "advapi32.dll", "RegEnumValueW" },
  1089.         { "advapi32.dll", "RegLoadKeyW" },
  1090.         { "advapi32.dll", "RegOpenKeyExW" },
  1091.         { "advapi32.dll", "RegOpenKeyW" },
  1092.         { "advapi32.dll", "RegQueryInfoKeyW" },
  1093.         { "advapi32.dll", "RegQueryMultipleValuesW" },
  1094.         { "advapi32.dll", "RegQueryValueExW" },
  1095.         { "advapi32.dll", "RegQueryValueW" },
  1096.         { "advapi32.dll", "RegReplaceKeyW" },
  1097.         { "advapi32.dll", "RegSaveKeyW" },
  1098.         { "advapi32.dll", "RegSetValueExW" },
  1099.         { "advapi32.dll", "RegSetValueW" },
  1100.         { "advapi32.dll", "RegUnLoadKeyW" },
  1101.         { "avicap32.dll", "capCreateCaptureWindowW" },
  1102.         { "avicap32.dll", "capGetDriverDescriptionW" },
  1103.         { "comdlg32.dll", "ChooseColorW" },
  1104.         { "comdlg32.dll", "ChooseFontW" },
  1105.         { "comdlg32.dll", "FindTextW" },
  1106.         { "comdlg32.dll", "GetFileTitleW" },
  1107.         { "comdlg32.dll", "GetOpenFileNameW" },
  1108.         { "comdlg32.dll", "GetSaveFileNameW" },
  1109.         { "comdlg32.dll", "PageSetupDlgW" },
  1110.         { "comdlg32.dll", "PrintDlgW" },
  1111.         { "comdlg32.dll", "ReplaceTextW" },
  1112.         { "gdi32.dll", "AddFontResourceW" },
  1113.         { "gdi32.dll", "CopyEnhMetaFileW" },
  1114.         { "gdi32.dll", "CopyMetaFileW" },
  1115.         { "gdi32.dll", "CreateColorSpaceW" },
  1116.         { "gdi32.dll", "CreateDCW" },
  1117.         { "gdi32.dll", "CreateEnhMetaFileW" },
  1118.         { "gdi32.dll", "CreateFontIndirectW" },
  1119.         { "gdi32.dll", "CreateFontW" },
  1120.         { "gdi32.dll", "CreateICW" },
  1121.         { "gdi32.dll", "CreateMetaFileW" },
  1122.         { "gdi32.dll", "CreateScalableFontResourceW" },
  1123.         { "gdi32.dll", "EnumFontFamiliesExW" },
  1124.         { "gdi32.dll", "EnumFontFamiliesW" },
  1125.         { "gdi32.dll", "EnumFontsW" },
  1126.         { "gdi32.dll", "EnumICMProfilesW" },
  1127.         { "gdi32.dll", "ExtTextOutW" },
  1128.         { "gdi32.dll", "GetCharABCWidthsFloatW" },
  1129.         { "gdi32.dll", "GetCharABCWidthsW" },
  1130.         { "gdi32.dll", "GetCharacterPlacementW" },
  1131.         { "gdi32.dll", "GetCharWidth32W" },
  1132.         { "gdi32.dll", "GetCharWidthFloatW" },
  1133.         { "gdi32.dll", "GetCharWidthW" },
  1134.         { "gdi32.dll", "GetEnhMetaFileDescriptionW" },
  1135.         { "gdi32.dll", "GetEnhMetaFileW" },
  1136.         { "gdi32.dll", "GetGlyphOutlineW" },
  1137.         { "gdi32.dll", "GetICMProfileW" },
  1138.         { "gdi32.dll", "GetKerningPairsW" },
  1139.         { "gdi32.dll", "GetLogColorSpaceW" },
  1140.         { "gdi32.dll", "GetMetaFileW" },
  1141.         { "gdi32.dll", "GetObjectW" },
  1142.         { "gdi32.dll", "GetOutlineTextMetricsW" },
  1143.         { "gdi32.dll", "GetTextExtentExPointW" },
  1144.         { "gdi32.dll", "GetTextExtentPoint32W" },
  1145.         { "gdi32.dll", "GetTextExtentPointW" },
  1146.         { "gdi32.dll", "GetTextFaceW" },
  1147.         { "gdi32.dll", "GetTextMetricsW" },
  1148.         { "gdi32.dll", "PolyTextOutW" },
  1149.         { "gdi32.dll", "RemoveFontResourceW" },
  1150.         { "gdi32.dll", "ResetDCW" },
  1151.         { "gdi32.dll", "SetICMProfileW" },
  1152.         { "gdi32.dll", "StartDocW" },
  1153.         { "gdi32.dll", "TextOutW" },
  1154.         { "gdi32.dll", "UpdateICMRegKeyW" },
  1155.         { "kernel32.dll", "AddAtomW" },
  1156.         { "kernel32.dll", "BeginUpdateResourceA" },
  1157.         { "kernel32.dll", "BeginUpdateResourceW" },
  1158.         { "kernel32.dll", "BuildCommDCBAndTimeoutsW" },
  1159.         { "kernel32.dll", "BuildCommDCBW" },
  1160.         { "kernel32.dll", "CallNamedPipeW" },
  1161.         { "kernel32.dll", "CommConfigDialogW" },
  1162.         { "kernel32.dll", "CompareStringW" },
  1163.         { "kernel32.dll", "CopyFileExW" },
  1164.         { "kernel32.dll", "CopyFileW" },
  1165.         { "kernel32.dll", "CreateDirectoryExW" },
  1166.         { "kernel32.dll", "CreateDirectoryW" },
  1167.         { "kernel32.dll", "CreateEventW" },
  1168.         { "kernel32.dll", "CreateFileMappingW" },
  1169.         { "kernel32.dll", "CreateFileW" },
  1170.         { "kernel32.dll", "CreateMailslotW" },
  1171.         { "kernel32.dll", "CreateMutexW" },
  1172.         { "kernel32.dll", "CreateNamedPipeW" },
  1173.         { "kernel32.dll", "CreateProcessW" },
  1174.         { "kernel32.dll", "CreateSemaphoreW" },
  1175.         { "kernel32.dll", "CreateWaitableTimerW" },
  1176.         { "kernel32.dll", "DeleteFileW" },
  1177.         { "kernel32.dll", "EndUpdateResourceA" },
  1178.         { "kernel32.dll", "EndUpdateResourceW" },
  1179.         { "kernel32.dll", "EnumCalendarInfoExW" },
  1180.         { "kernel32.dll", "EnumCalendarInfoW" },
  1181.         { "kernel32.dll", "EnumDateFormatsExW" },
  1182.         { "kernel32.dll", "EnumDateFormatsW" },
  1183.         { "kernel32.dll", "EnumSystemCodePagesW" },
  1184.         { "kernel32.dll", "EnumSystemLocalesW" },
  1185.         { "kernel32.dll", "EnumTimeFormatsW" },
  1186.         { "kernel32.dll", "ExpandEnvironmentStringsW" },
  1187.         { "kernel32.dll", "FatalAppExitW" },
  1188.         { "kernel32.dll", "FillConsoleOutputCharacterW" },
  1189.         { "kernel32.dll", "FindAtomW" },
  1190.         { "kernel32.dll", "FindFirstChangeNotificationW" },
  1191.         { "kernel32.dll", "FindFirstFileW" },
  1192.         { "kernel32.dll", "FindNextFileW" },
  1193.         { "kernel32.dll", "FindResourceExW" },
  1194.         { "kernel32.dll", "FindResourceW" },
  1195.         { "kernel32.dll", "FormatMessageW" },
  1196.         { "kernel32.dll", "FreeEnvironmentStringsW" },
  1197.         { "kernel32.dll", "GetAtomNameW" },
  1198.         { "kernel32.dll", "GetCalendarInfoW" },
  1199.         { "kernel32.dll", "GetComputerNameW" },
  1200.         { "kernel32.dll", "GetConsoleTitleW" },
  1201.         { "kernel32.dll", "GetCPInfo" },
  1202.         { "kernel32.dll", "GetCPInfoExW" },
  1203.         { "kernel32.dll", "GetCurrencyFormatW" },
  1204.         { "kernel32.dll", "GetCurrentDirectoryW" },
  1205.         { "kernel32.dll", "GetDateFormatW" },
  1206.         { "kernel32.dll", "GetDefaultCommConfigW" },
  1207.         { "kernel32.dll", "GetDiskFreeSpaceExW" },
  1208.         { "kernel32.dll", "GetDiskFreeSpaceW" },
  1209.         { "kernel32.dll", "GetDriveTypeW" },
  1210.         { "kernel32.dll", "GetEnvironmentStringsW" },
  1211.         { "kernel32.dll", "GetEnvironmentVariableW" },
  1212.         { "kernel32.dll", "GetFileAttributesExW" },
  1213.         { "kernel32.dll", "GetFileAttributesW" },
  1214.         { "kernel32.dll", "GetFullPathNameW" },
  1215.         { "kernel32.dll", "GetLocaleInfoW" },
  1216.         { "kernel32.dll", "GetLogicalDriveStringsW" },
  1217.         { "kernel32.dll", "GetLongPathNameW" },
  1218.         { "kernel32.dll", "GetModuleFileNameW" },
  1219.         { "kernel32.dll", "GetModuleHandleW" },
  1220.         { "kernel32.dll", "GetNamedPipeHandleStateW" },
  1221.         { "kernel32.dll", "GetNumberFormatW" },
  1222.         { "kernel32.dll", "GetPrivateProfileIntW" },
  1223.         { "kernel32.dll", "GetPrivateProfileSectionNamesW" },
  1224.         { "kernel32.dll", "GetPrivateProfileSectionW" },
  1225.         { "kernel32.dll", "GetPrivateProfileStringW" },
  1226.         { "kernel32.dll", "GetPrivateProfileStructW" },
  1227.         { "kernel32.dll", "GetProcAddress" },
  1228.         { "kernel32.dll", "GetProfileIntW" },
  1229.         { "kernel32.dll", "GetProfileSectionW" },
  1230.         { "kernel32.dll", "GetProfileStringW" },
  1231.         { "kernel32.dll", "GetShortPathNameW" },
  1232.         { "kernel32.dll", "GetStartupInfoW" },
  1233.         { "kernel32.dll", "GetStringTypeExW" },
  1234.         { "kernel32.dll", "GetStringTypeW" },
  1235.         { "kernel32.dll", "GetSystemDirectoryW" },
  1236.         { "kernel32.dll", "GetSystemWindowsDirectoryW" },
  1237.         { "kernel32.dll", "GetTempFileNameW" },
  1238.         { "kernel32.dll", "GetTempPathW" },
  1239.         { "kernel32.dll", "GetTimeFormatW" },
  1240.         { "kernel32.dll", "GetVersionExW" },
  1241.         { "kernel32.dll", "GetVolumeInformationW" },
  1242.         { "kernel32.dll", "GetWindowsDirectoryW" },
  1243.         { "kernel32.dll", "GlobalAddAtomW" },
  1244.         { "kernel32.dll", "GlobalFindAtomW" },
  1245.         { "kernel32.dll", "GlobalGetAtomNameW" },
  1246.         { "kernel32.dll", "IsBadStringPtrW" },
  1247.         { "kernel32.dll", "IsValidCodePage" },
  1248.         { "kernel32.dll", "LCMapStringW" },
  1249.         { "kernel32.dll", "LoadLibraryExW" },
  1250.         { "kernel32.dll", "LoadLibraryW" },
  1251.         { "kernel32.dll", "lstrcatW" },
  1252.         { "kernel32.dll", "lstrcmpiW" },
  1253.         { "kernel32.dll", "lstrcmpW" },
  1254.         { "kernel32.dll", "lstrcpynW" },
  1255.         { "kernel32.dll", "lstrcpyW" },
  1256.         { "kernel32.dll", "lstrlenW" },
  1257.         { "kernel32.dll", "MoveFileW" },
  1258.         { "kernel32.dll", "MultiByteToWideChar" },
  1259.         { "kernel32.dll", "OpenEventW" },
  1260.         { "kernel32.dll", "OpenFileMappingW" },
  1261.         { "kernel32.dll", "OpenMutexW" },
  1262.         { "kernel32.dll", "OpenSemaphoreW" },
  1263.         { "kernel32.dll", "OpenWaitableTimerW" },
  1264.         { "kernel32.dll", "OutputDebugStringW" },
  1265.         { "kernel32.dll", "PeekConsoleInputW" },
  1266.         { "kernel32.dll", "QueryDosDeviceW" },
  1267.         { "kernel32.dll", "ReadConsoleInputW" },
  1268.         { "kernel32.dll", "ReadConsoleOutputCharacterW" },
  1269.         { "kernel32.dll", "ReadConsoleOutputW" },
  1270.         { "kernel32.dll", "ReadConsoleW" },
  1271.         { "kernel32.dll", "RemoveDirectoryW" },
  1272.         { "kernel32.dll", "ScrollConsoleScreenBufferW" },
  1273.         { "kernel32.dll", "SearchPathW" },
  1274.         { "kernel32.dll", "SetCalendarInfoW" },
  1275.         { "kernel32.dll", "SetComputerNameW" },
  1276.         { "kernel32.dll", "SetConsoleTitleW" },
  1277.         { "kernel32.dll", "SetCurrentDirectoryW" },
  1278.         { "kernel32.dll", "SetDefaultCommConfigW" },
  1279.         { "kernel32.dll", "SetEnvironmentVariableW" },
  1280.         { "kernel32.dll", "SetFileAttributesW" },
  1281.         { "kernel32.dll", "SetLocaleInfoW" },
  1282.         { "kernel32.dll", "SetVolumeLabelW" },
  1283.         { "kernel32.dll", "UpdateResourceA" },
  1284.         { "kernel32.dll", "UpdateResourceW" },
  1285.         { "kernel32.dll", "WaitNamedPipeW" },
  1286.         { "kernel32.dll", "WideCharToMultiByte" },
  1287.         { "kernel32.dll", "WriteConsoleInputW" },
  1288.         { "kernel32.dll", "WriteConsoleOutputCharacterW" },
  1289.         { "kernel32.dll", "WriteConsoleOutputW" },
  1290.         { "kernel32.dll", "WriteConsoleW" },
  1291.         { "kernel32.dll", "WritePrivateProfileSectionW" },
  1292.         { "kernel32.dll", "WritePrivateProfileStringW" },
  1293.         { "kernel32.dll", "WritePrivateProfileStructW" },
  1294.         { "kernel32.dll", "WriteProfileSectionW" },
  1295.         { "kernel32.dll", "WriteProfileStringW" },
  1296.         { "mpr.dll", "MultinetGetConnectionPerformanceW" },
  1297.         { "mpr.dll", "WNetAddConnection2W" },
  1298.         { "mpr.dll", "WNetAddConnection3W" },
  1299.         { "mpr.dll", "WNetAddConnectionW" },
  1300.         { "mpr.dll", "WNetCancelConnection2W" },
  1301.         { "mpr.dll", "WNetCancelConnectionW" },
  1302.         { "mpr.dll", "WNetConnectionDialog1W" },
  1303.         { "mpr.dll", "WNetDisconnectDialog1W" },
  1304.         { "mpr.dll", "WNetEnumResourceW" },
  1305.         { "mpr.dll", "WNetGetConnectionW" },
  1306.         { "mpr.dll", "WNetGetLastErrorW" },
  1307.         { "mpr.dll", "WNetGetNetworkInformationW" },
  1308.         { "mpr.dll", "WNetGetProviderNameW" },
  1309.         { "mpr.dll", "WNetGetResourceInformationW" },
  1310.         { "mpr.dll", "WNetGetResourceParentW" },
  1311.         { "mpr.dll", "WNetGetUniversalNameW" },
  1312.         { "mpr.dll", "WNetGetUserW" },
  1313.         { "mpr.dll", "WNetOpenEnumW" },
  1314.         { "mpr.dll", "WNetUseConnectionW" },
  1315.         { "msvcrt.dll", "_waccess" },
  1316.         { "msvcrt.dll", "_wchdir" },
  1317.         { "msvcrt.dll", "_wgetcwd" },
  1318.         { "msvcrt.dll", "_wgetdcwd" },
  1319.         { "msvcrt.dll", "_wmkdir" },
  1320.         { "msvcrt.dll", "_wopen" },
  1321.         { "msvcrt.dll", "_wremove" },
  1322.         { "msvcrt.dll", "_wrename" },
  1323.         { "msvcrt.dll", "_wstat" },
  1324.         { "msvcrt.dll", "_wstati64" },
  1325.         { "msvfw32.dll", "GetOpenFileNamePreviewW" },
  1326.         { "msvfw32.dll", "GetSaveFileNamePreviewW" },
  1327.         { "msvfw32.dll", "MCIWndCreateW" },
  1328.         { "oleacc.dll", "CreateStdAccessibleProxyW" },
  1329.         { "oleacc.dll", "GetRoleTextW" },
  1330.         { "oleacc.dll", "GetStateTextW" },
  1331.         { "oledlg.dll", "OleUIAddVerbMenuW" },
  1332.         { "oledlg.dll", "OleUIBusyW" },
  1333.         { "oledlg.dll", "OleUIChangeIconW" },
  1334.         { "oledlg.dll", "OleUIChangeSourceW" },
  1335.         { "oledlg.dll", "OleUIConvertW" },
  1336.         { "oledlg.dll", "OleUIEditLinksW" },
  1337.         { "oledlg.dll", "OleUIInsertObjectW" },
  1338.         { "oledlg.dll", "OleUIObjectPropertiesW" },
  1339.         { "oledlg.dll", "OleUIPasteSpecialW" },
  1340.         { "oledlg.dll", "OleUIPromptUserW" },
  1341.         { "oledlg.dll", "OleUIUpdateLinksW" },
  1342.         { "rasapi32.dll", "RasConnectionNotificationW" },
  1343.         { "rasapi32.dll", "RasCreatePhonebookEntryW" },
  1344.         { "rasapi32.dll", "RasDeleteEntryW" },
  1345.         { "rasapi32.dll", "RasDeleteSubEntryW" },
  1346.         { "rasapi32.dll", "RasDialW" },
  1347.         { "rasapi32.dll", "RasEditPhonebookEntryW" },
  1348.         { "rasapi32.dll", "RasEnumConnectionsW" },
  1349.         { "rasapi32.dll", "RasEnumDevicesW" },
  1350.         { "rasapi32.dll", "RasEnumEntriesW" },
  1351.         { "rasapi32.dll", "RasGetConnectStatusW" },
  1352.         { "rasapi32.dll", "RasGetEntryDialParamsW" },
  1353.         { "rasapi32.dll", "RasGetEntryPropertiesW" },
  1354.         { "rasapi32.dll", "RasGetErrorStringW" },
  1355.         { "rasapi32.dll", "RasGetProjectionInfoW" },
  1356.         { "rasapi32.dll", "RasHangUpW" },
  1357.         { "rasapi32.dll", "RasRenameEntryW" },
  1358.         { "rasapi32.dll", "RasSetEntryDialParamsW" },
  1359.         { "rasapi32.dll", "RasSetEntryPropertiesW" },
  1360.         { "rasapi32.dll", "RasSetSubEntryPropertiesW" },
  1361.         { "rasapi32.dll", "RasValidateEntryNameW" },
  1362.         { "secur32.dll", "AcquireCredentialsHandleW" },
  1363.         { "secur32.dll", "EnumerateSecurityPackagesW" },
  1364.         { "secur32.dll", "FreeContextBuffer" },
  1365.         { "secur32.dll", "InitializeSecurityContextW" },
  1366.         { "secur32.dll", "InitSecurityInterfaceW" },
  1367.         { "secur32.dll", "QueryContextAttributesW" },
  1368.         { "secur32.dll", "QueryCredentialsAttributesW" },
  1369.         { "secur32.dll", "QuerySecurityPackageInfoW" },
  1370.         { "sensapi.dll", "IsDestinationReachableW" },
  1371.         { "shell32.dll", "DragQueryFileW" },
  1372.         { "shell32.dll", "ExtractIconExW" },
  1373.         { "shell32.dll", "ExtractIconW" },
  1374.         { "shell32.dll", "FindExecutableW" },
  1375.         { "shell32.dll", "SHBrowseForFolderW" },
  1376.         { "shell32.dll", "SHChangeNotify" },
  1377.         { "shell32.dll", "Shell_NotifyIconW" },
  1378.         { "shell32.dll", "ShellAboutW" },
  1379.         { "shell32.dll", "ShellExecuteExW" },
  1380.         { "shell32.dll", "ShellExecuteW" },
  1381.         { "shell32.dll", "SHFileOperationW" },
  1382.         { "shell32.dll", "SHGetFileInfoW" },
  1383.         { "shell32.dll", "SHGetNewLinkInfoW" },
  1384.         { "shell32.dll", "SHGetPathFromIDListW" },
  1385.         { "user32.dll", "AppendMenuW" },
  1386.         { "user32.dll", "BroadcastSystemMessageW" },
  1387.         { "user32.dll", "CallMsgFilterW" },
  1388.         { "user32.dll", "CallWindowProcA" },
  1389.         { "user32.dll", "CallWindowProcW" },
  1390.         { "user32.dll", "ChangeDisplaySettingsExW" },
  1391.         { "user32.dll", "ChangeDisplaySettingsW" },
  1392.         { "user32.dll", "ChangeMenuW" },
  1393.         { "user32.dll", "CharLowerBuffW" },
  1394.         { "user32.dll", "CharLowerW" },
  1395.         { "user32.dll", "CharNextW" },
  1396.         { "user32.dll", "CharPrevW" },
  1397.         { "user32.dll", "CharToOemBuffW" },
  1398.         { "user32.dll", "CharToOemW" },
  1399.         { "user32.dll", "CharUpperBuffW" },
  1400.         { "user32.dll", "CharUpperW" },
  1401.         { "user32.dll", "CopyAcceleratorTableW" },
  1402.         { "user32.dll", "CreateAcceleratorTableW" },
  1403.         { "user32.dll", "CreateDialogIndirectParamW" },
  1404.         { "user32.dll", "CreateDialogParamW" },
  1405.         { "user32.dll", "CreateMDIWindowW" },
  1406.         { "user32.dll", "CreateWindowExW" },
  1407.         { "user32.dll", "DdeConnect" },
  1408.         { "user32.dll", "DdeConnectList" },
  1409.         { "user32.dll", "DdeCreateStringHandleW" },
  1410.         { "user32.dll", "DdeInitializeW" },
  1411.         { "user32.dll", "DdeQueryConvInfo" },
  1412.         { "user32.dll", "DdeQueryStringW" },
  1413.         { "user32.dll", "DefDlgProcW" },
  1414.         { "user32.dll", "DefFrameProcW" },
  1415.         { "user32.dll", "DefMDIChildProcW" },
  1416.         { "user32.dll", "DefWindowProcW" },
  1417.         { "user32.dll", "DialogBoxIndirectParamW" },
  1418.         { "user32.dll", "DialogBoxParamW" },
  1419.         { "user32.dll", "DispatchMessageW" },
  1420.         { "user32.dll", "DlgDirListComboBoxW" },
  1421.         { "user32.dll", "DlgDirListW" },
  1422.         { "user32.dll", "DlgDirSelectComboBoxExW" },
  1423.         { "user32.dll", "DlgDirSelectExW" },
  1424.         { "user32.dll", "DrawStateW" },
  1425.         { "user32.dll", "DrawTextExW" },
  1426.         { "user32.dll", "DrawTextW" },
  1427.         { "user32.dll", "EnableWindow" },
  1428.         { "user32.dll", "EnumClipboardFormats" },
  1429.         { "user32.dll", "EnumDisplayDevicesW" },
  1430.         { "user32.dll", "EnumDisplaySettingsExW" },
  1431.         { "user32.dll", "EnumDisplaySettingsW" },
  1432.         { "user32.dll", "EnumPropsA" },
  1433.         { "user32.dll", "EnumPropsExA" },
  1434.         { "user32.dll", "EnumPropsExW" },
  1435.         { "user32.dll", "EnumPropsW" },
  1436.         { "user32.dll", "FindWindowExW" },
  1437.         { "user32.dll", "FindWindowW" },
  1438.         { "user32.dll", "GetAltTabInfoW" },
  1439.         { "user32.dll", "GetClassInfoExW" },
  1440.         { "user32.dll", "GetClassInfoW" },
  1441.         { "user32.dll", "GetClassLongW" },
  1442.         { "user32.dll", "GetClassNameW" },
  1443.         { "user32.dll", "GetClipboardData" },
  1444.         { "user32.dll", "GetClipboardFormatNameW" },
  1445.         { "user32.dll", "GetDlgItemTextW" },
  1446.         { "user32.dll", "GetKeyboardLayoutNameW" },
  1447.         { "user32.dll", "GetKeyNameTextW" },
  1448.         { "user32.dll", "GetMenuItemInfoW" },
  1449.         { "user32.dll", "GetMenuStringW" },
  1450.         { "user32.dll", "GetMessageW" },
  1451.         { "user32.dll", "GetMonitorInfoW" },
  1452.         { "user32.dll", "GetPropA" },
  1453.         { "user32.dll", "GetPropW" },
  1454.         { "user32.dll", "GetTabbedTextExtentW" },
  1455.         { "user32.dll", "GetWindowLongA" },
  1456.         { "user32.dll", "GetWindowLongW" },
  1457.         { "user32.dll", "GetWindowModuleFileNameW" },
  1458.         { "user32.dll", "GetWindowTextLengthW" },
  1459.         { "user32.dll", "GetWindowTextW" },
  1460.         { "user32.dll", "GrayStringW" },
  1461.         { "user32.dll", "InsertMenuItemW" },
  1462.         { "user32.dll", "InsertMenuW" },
  1463.         { "user32.dll", "IsCharAlphaNumericW" },
  1464.         { "user32.dll", "IsCharAlphaW" },
  1465.         { "user32.dll", "IsCharLowerW" },
  1466.         { "user32.dll", "IsCharUpperW" },
  1467.         { "user32.dll", "IsClipboardFormatAvailable" },
  1468.         { "user32.dll", "IsDialogMessageW" },
  1469.         { "user32.dll", "IsWindowUnicode" },
  1470.         { "user32.dll", "LoadAcceleratorsW" },
  1471.         { "user32.dll", "LoadBitmapW" },
  1472.         { "user32.dll", "LoadCursorFromFileW" },
  1473.         { "user32.dll", "LoadCursorW" },
  1474.         { "user32.dll", "LoadIconW" },
  1475.         { "user32.dll", "LoadImageW" },
  1476.         { "user32.dll", "LoadKeyboardLayoutW" },
  1477.         { "user32.dll", "LoadMenuIndirectW" },
  1478.         { "user32.dll", "LoadMenuW" },
  1479.         { "user32.dll", "LoadStringW" },
  1480.         { "user32.dll", "MapVirtualKeyExW" },
  1481.         { "user32.dll", "MapVirtualKeyW" },
  1482.         { "user32.dll", "MessageBoxExW" },
  1483.         { "user32.dll", "MessageBoxIndirectW" },
  1484.         { "user32.dll", "MessageBoxW" },
  1485.         { "user32.dll", "ModifyMenuW" },
  1486.         { "user32.dll", "OemToCharBuffW" },
  1487.         { "user32.dll", "OemToCharW" },
  1488.         { "user32.dll", "PeekMessageW" },
  1489.         { "user32.dll", "PostMessageW" },
  1490.         { "user32.dll", "PostThreadMessageW" },
  1491.         { "user32.dll", "RegisterClassExW" },
  1492.         { "user32.dll", "RegisterClassW" },
  1493.         { "user32.dll", "RegisterClipboardFormatW" },
  1494.         { "user32.dll", "RegisterDeviceNotificationW" },
  1495.         { "user32.dll", "RegisterWindowMessageW" },
  1496.         { "user32.dll", "RemovePropA" },
  1497.         { "user32.dll", "RemovePropW" },
  1498.         { "user32.dll", "SendDlgItemMessageW" },
  1499.         { "user32.dll", "SendMessageCallbackW" },
  1500.         { "user32.dll", "SendMessageTimeoutW" },
  1501.         { "user32.dll", "SendMessageW" },
  1502.         { "user32.dll", "SendNotifyMessageW" },
  1503.         { "user32.dll", "SetClassLongW" },
  1504.         { "user32.dll", "SetDlgItemTextW" },
  1505.         { "user32.dll", "SetMenuItemInfoW" },
  1506.         { "user32.dll", "SetPropA" },
  1507.         { "user32.dll", "SetPropW" },
  1508.         { "user32.dll", "SetWindowLongA" },
  1509.         { "user32.dll", "SetWindowLongW" },
  1510.         { "user32.dll", "SetWindowsHookExW" },
  1511.         { "user32.dll", "SetWindowsHookW" },
  1512.         { "user32.dll", "SetWindowTextW" },
  1513.         { "user32.dll", "SystemParametersInfoW" },
  1514.         { "user32.dll", "TabbedTextOutW" },
  1515.         { "user32.dll", "TranslateAcceleratorW" },
  1516.         { "user32.dll", "UnregisterClassW" },
  1517.         { "user32.dll", "VkKeyScanExW" },
  1518.         { "user32.dll", "VkKeyScanW" },
  1519.         { "user32.dll", "WinHelpW" },
  1520.         { "user32.dll", "wsprintfW" },
  1521.         { "user32.dll", "wvsprintfW" },
  1522.         { "version.dll", "GetFileVersionInfoSizeW" },
  1523.         { "version.dll", "GetFileVersionInfoW" },
  1524.         { "version.dll", "VerFindFileW" },
  1525.         { "version.dll", "VerInstallFileW" },
  1526.         { "version.dll", "VerLanguageNameW" },
  1527.         { "version.dll", "VerQueryValueW" },
  1528.         { "winmm.dll", "auxGetDevCapsW" },
  1529.         { "winmm.dll", "joyGetDevCapsW" },
  1530.         { "winmm.dll", "mciGetDeviceIDW" },
  1531.         { "winmm.dll", "mciGetErrorStringW" },
  1532.         { "winmm.dll", "mciSendCommandW" },
  1533.         { "winmm.dll", "mciSendStringW" },
  1534.         { "winmm.dll", "midiInGetDevCapsW" },
  1535.         { "winmm.dll", "midiInGetErrorTextW" },
  1536.         { "winmm.dll", "midiOutGetDevCapsW" },
  1537.         { "winmm.dll", "midiOutGetErrorTextW" },
  1538.         { "winmm.dll", "mixerGetControlDetailsW" },
  1539.         { "winmm.dll", "mixerGetDevCapsW" },
  1540.         { "winmm.dll", "mixerGetLineControlsW" },
  1541.         { "winmm.dll", "mixerGetLineInfoW" },
  1542.         { "winmm.dll", "mmioInstallIOProcW" },
  1543.         { "winmm.dll", "mmioOpenW" },
  1544.         { "winmm.dll", "mmioRenameW" },
  1545.         { "winmm.dll", "mmioStringToFOURCCW" },
  1546.         { "winmm.dll", "PlaySoundW" },
  1547.         { "winmm.dll", "sndPlaySoundW" },
  1548.         { "winmm.dll", "waveInGetDevCapsW" },
  1549.         { "winmm.dll", "waveInGetErrorTextW" },
  1550.         { "winmm.dll", "waveOutGetDevCapsW" },
  1551.         { "winmm.dll", "waveOutGetErrorTextW" },
  1552.         { "winspool.drv", "AddJobW" },
  1553.         { "winspool.drv", "AddMonitorW" },
  1554.         { "winspool.drv", "AddPortW" },
  1555.         { "winspool.drv", "AddPrinterDriverW" },
  1556.         { "winspool.drv", "AddPrinterW" },
  1557.         { "winspool.drv", "AddPrintProcessorW" },
  1558.         { "winspool.drv", "AddPrintProvidorW" },
  1559.         { "winspool.drv", "AdvancedDocumentPropertiesW" },
  1560.         { "winspool.drv", "ConfigurePortW" },
  1561.         { "winspool.drv", "DeleteMonitorW" },
  1562.         { "winspool.drv", "DeletePortW" },
  1563.         { "winspool.drv", "DeletePrinterDriverW" },
  1564.         { "winspool.drv", "DeletePrintProcessorW" },
  1565.         { "winspool.drv", "DeletePrintProvidorW" },
  1566.         { "winspool.drv", "DeviceCapabilitiesW" },
  1567.         { "winspool.drv", "DocumentPropertiesW" },
  1568.         { "winspool.drv", "EnumMonitorsW" },
  1569.         { "winspool.drv", "EnumPortsW" },
  1570.         { "winspool.drv", "EnumPrinterDriversW" },
  1571.         { "winspool.drv", "EnumPrintersW" },
  1572.         { "winspool.drv", "EnumPrintProcessorDatatypesW" },
  1573.         { "winspool.drv", "EnumPrintProcessorsW" },
  1574.         { "winspool.drv", "GetJobW" },
  1575.         { "winspool.drv", "GetPrinterDataW" },
  1576.         { "winspool.drv", "GetPrinterDriverDirectoryW" },
  1577.         { "winspool.drv", "GetPrinterDriverW" },
  1578.         { "winspool.drv", "GetPrinterW" },
  1579.         { "winspool.drv", "GetPrintProcessorDirectoryW" },
  1580.         { "winspool.drv", "OpenPrinterW" },
  1581.         { "winspool.drv", "ResetPrinterW" },
  1582.         { "winspool.drv", "SetJobW" },
  1583.         { "winspool.drv", "SetPrinterDataW" },
  1584.         { "winspool.drv", "SetPrinterW" },
  1585.         { "winspool.drv", "StartDocPrinterW" }
  1586.     };
  1587.  
  1588.     // if they are calling it on our DLL directly then let kernel32 handle it,
  1589.     // because we know it will return the correct value as necessary
  1590.     if (hModule == (HMODULE) g_hInstanceDLL)
  1591.         return ::GetProcAddress(hModule, lpProcName);
  1592.  
  1593.     // get the system path once
  1594.     static char szSystemPath[MAX_PATH+1] = { 0 };
  1595.     if (!*szSystemPath) {
  1596.         if (!::GetSystemDirectoryA(szSystemPath, sizeof(szSystemPath)))
  1597.             return NULL;
  1598.     }
  1599.  
  1600.     // determine the path for the DLL that they have requested the
  1601.     // function for.
  1602.     char szModulePath[MAX_PATH+1];
  1603.     if (!::GetModuleFileNameA(hModule, szModulePath, sizeof(szModulePath)))
  1604.         return NULL;
  1605.     char * pszModuleName = (char *) ::_mbsrchr((unsigned char *)szModulePath, '\\');
  1606.     if (!pszModuleName) {
  1607.         SetLastError(ERROR_PROC_NOT_FOUND);
  1608.         return NULL;
  1609.     }
  1610.     *pszModuleName++ = 0;
  1611.  
  1612.     // we only check to see if we load our own implementation of this function
  1613.     // if the requested DLL is in the system path.
  1614.     if (0 == ::strcmp(szModulePath, szSystemPath))
  1615.     {
  1616.         MsluExport searchTerm = { pszModuleName, lpProcName };
  1617.         MsluExport * pEntry = (MsluExport *) ::bsearch(
  1618.             &searchTerm, rgCheckedExports,
  1619.             sizeof(rgCheckedExports)/sizeof(rgCheckedExports[0]),
  1620.             sizeof(rgCheckedExports[0]),
  1621.             OCOW_Compare);
  1622.         if (pEntry) {
  1623.             FARPROC pProc = ::GetProcAddress(g_hInstanceDLL, lpProcName);
  1624.             if (g_nDebug >= 2) {
  1625.                 char szMessage[256];
  1626.                 if (pProc)
  1627.                     lstrcpyA(szMessage, "Successfully loaded opencow function '");
  1628.                 else
  1629.                     lstrcpyA(szMessage, "Failed to load opencow function '");
  1630.                 lstrcatA(szMessage, lpProcName);
  1631.                 lstrcatA(szMessage, "' from '");
  1632.                 lstrcatA(szMessage, pszModuleName);
  1633.                 lstrcatA(szMessage, "'. Press cancel to disable getprocaddress notifications.");
  1634.  
  1635.                 int nResult = ::MessageBoxA(NULL, szMessage, "opencow",
  1636.                     MB_OKCANCEL | MB_SETFOREGROUND);
  1637.                 if (nResult == IDCANCEL)
  1638.                     g_nDebug = 1;
  1639.             }
  1640.             return pProc;
  1641.         }
  1642.     }
  1643.  
  1644.     // if we haven't found the procedure we pass it on to the kernel
  1645.     return ::GetProcAddress(hModule, lpProcName);
  1646. }
  1647. #endif
  1648. // GetProfileIntW
  1649. // GetProfileSectionW
  1650. // GetProfileStringW
  1651.  
  1652. extern "C" DWORD WINAPI
  1653. zGetShortPathNameW(
  1654.     IN LPCWSTR  lpszLongPath,
  1655.     OUT LPWSTR  lpszShortPath,
  1656.     IN DWORD    cchBuffer
  1657.     )
  1658. {
  1659.     CMbcsBuffer mbcsLongPath;
  1660.     if (!mbcsLongPath.FromUnicode(lpszLongPath))
  1661.         return 0;
  1662.  
  1663.     DWORD dwResult = 0;
  1664.     CMbcsBuffer mbcsShortPath;
  1665.     do {
  1666.         if (dwResult > (DWORD) mbcsShortPath.BufferSize()) {
  1667.             if (!mbcsShortPath.SetCapacity((int) dwResult))
  1668.                 return 0;
  1669.         }
  1670.  
  1671.         dwResult = ::GetShortPathNameA(mbcsLongPath, mbcsShortPath, (DWORD) mbcsShortPath.BufferSize());
  1672.         if (!dwResult)
  1673.             return 0;
  1674.     }
  1675.     while (dwResult > (DWORD) mbcsShortPath.BufferSize());
  1676.     int nShortPathLen = ::lstrlenA(mbcsShortPath);
  1677.  
  1678.     // ensure the supplied buffer is big enough
  1679.     int nRequiredSize = ::MultiByteToWideChar(CP_ACP, 0, mbcsShortPath, nShortPathLen + 1, 0, 0);
  1680.     if (cchBuffer < (DWORD) nRequiredSize)
  1681.         return (DWORD) nRequiredSize;
  1682.  
  1683.     ::MultiByteToWideChar(CP_ACP, 0, mbcsShortPath, nShortPathLen + 1, lpszShortPath, cchBuffer);
  1684.     return nRequiredSize - 1; // do not include the NULL
  1685. }
  1686. #if 0
  1687. VOID WINAPI
  1688. GetStartupInfoW(
  1689.     OUT LPSTARTUPINFOW lpStartupInfo
  1690.     )
  1691. {
  1692.     // we use static buffers here because they must be valid for the caller
  1693.     // to use after we have returned. Also, we know that they will not change
  1694.     // from call to call because this is information which was generated at
  1695.     // application startup time and is never changed from then.
  1696.     static bool bIsInitialized = false;
  1697.     static wchar_t wszDesktop[MAX_PATH] = { 0 };
  1698.     static wchar_t wszTitle[MAX_PATH] = { 0 };
  1699.     static STARTUPINFOA startupInfoA = { 0 };
  1700.     if (!bIsInitialized) {
  1701.         ::GetStartupInfoA(&startupInfoA);
  1702.         ::MultiByteToWideChar(CP_ACP, 0, startupInfoA.lpDesktop, -1, wszDesktop, MAX_PATH);
  1703.         ::MultiByteToWideChar(CP_ACP, 0, startupInfoA.lpTitle, -1, wszTitle, MAX_PATH);
  1704.         bIsInitialized = true;
  1705.     }
  1706.  
  1707.     ::ZeroMemory(lpStartupInfo, sizeof(STARTUPINFOW));
  1708.     lpStartupInfo->cb               = sizeof(STARTUPINFOW);
  1709.     lpStartupInfo->dwX              = startupInfoA.dwX;
  1710.     lpStartupInfo->dwY              = startupInfoA.dwY;
  1711.     lpStartupInfo->dwXSize          = startupInfoA.dwXSize;
  1712.     lpStartupInfo->dwYSize          = startupInfoA.dwYSize;
  1713.     lpStartupInfo->dwXCountChars    = startupInfoA.dwXCountChars;
  1714.     lpStartupInfo->dwYCountChars    = startupInfoA.dwYCountChars;
  1715.     lpStartupInfo->dwFillAttribute  = startupInfoA.dwFillAttribute;
  1716.     lpStartupInfo->dwFlags          = startupInfoA.dwFlags;
  1717.     lpStartupInfo->wShowWindow      = startupInfoA.wShowWindow;
  1718.     lpStartupInfo->hStdInput        = startupInfoA.hStdInput;
  1719.     lpStartupInfo->hStdOutput       = startupInfoA.hStdOutput;
  1720.     lpStartupInfo->hStdError        = startupInfoA.hStdError;
  1721.  
  1722.     if (startupInfoA.lpDesktop)
  1723.         lpStartupInfo->lpDesktop = wszDesktop;
  1724.     if (startupInfoA.lpTitle)
  1725.         lpStartupInfo->lpTitle = wszTitle;
  1726. }
  1727. #endif
  1728. // GetStringTypeExW
  1729.  
  1730. extern "C" BOOL WINAPI
  1731. zGetStringTypeW(
  1732.     IN DWORD    dwInfoType,
  1733.     IN LPCWSTR  lpSrcStr,
  1734.     IN int      cchSrc,
  1735.     OUT LPWORD  lpCharType
  1736.     )
  1737. {
  1738.     CMbcsBuffer mbcsString;
  1739.     if (!mbcsString.FromUnicode(lpSrcStr, cchSrc))
  1740.         return FALSE;
  1741.  
  1742.     return ::GetStringTypeA(LOCALE_SYSTEM_DEFAULT, dwInfoType,
  1743.         mbcsString, mbcsString.Length(), lpCharType);
  1744. }
  1745. #if 0
  1746. UINT WINAPI
  1747. GetSystemDirectoryW(
  1748.     OUT LPWSTR lpBuffer,
  1749.     IN UINT uSize
  1750.     )
  1751. {
  1752.     DWORD dwResult = 0;
  1753.     CMbcsBuffer mbcsBuffer;
  1754.     do {
  1755.         if (dwResult > (DWORD) mbcsBuffer.BufferSize()) {
  1756.             if (!mbcsBuffer.SetCapacity((int) dwResult))
  1757.                 return 0;
  1758.         }
  1759.  
  1760.         dwResult = ::GetSystemDirectoryA(mbcsBuffer, (DWORD) mbcsBuffer.BufferSize());
  1761.         if (!dwResult)
  1762.             return 0;
  1763.     }
  1764.     while (dwResult > (DWORD) mbcsBuffer.BufferSize());
  1765.     int nBufferLen = ::lstrlenA(mbcsBuffer);
  1766.  
  1767.     // ensure the supplied buffer is big enough
  1768.     int nRequiredSize = ::MultiByteToWideChar(CP_ACP, 0, mbcsBuffer, nBufferLen + 1, 0, 0);
  1769.     if (uSize < (DWORD) nRequiredSize)
  1770.         return (DWORD) nRequiredSize;
  1771.  
  1772.     ::MultiByteToWideChar(CP_ACP, 0, mbcsBuffer, nBufferLen + 1, lpBuffer, uSize);
  1773.     return nRequiredSize - 1; // do not include the NULL
  1774. }
  1775.  
  1776. UINT WINAPI
  1777. GetSystemWindowsDirectoryW(
  1778.     OUT LPWSTR lpBuffer,
  1779.     IN UINT uSize
  1780.     )
  1781. {
  1782.     DWORD dwResult = 0;
  1783.     CMbcsBuffer mbcsBuffer;
  1784.     do {
  1785.         if (dwResult > (DWORD) mbcsBuffer.BufferSize()) {
  1786.             if (!mbcsBuffer.SetCapacity((int) dwResult))
  1787.                 return 0;
  1788.         }
  1789.  
  1790.         // The GetSystemWindowsDirectoryA function doesn't exist on Windows 95/98/ME.
  1791.         // As the result is the shared windows directory, this is the same as the
  1792.         // standard GetWindowsDirectoryA call on these platforms.
  1793.         dwResult = ::GetWindowsDirectoryA(mbcsBuffer, (DWORD) mbcsBuffer.BufferSize());
  1794.         if (!dwResult)
  1795.             return 0;
  1796.     }
  1797.     while (dwResult > (DWORD) mbcsBuffer.BufferSize());
  1798.     int nBufferLen = ::lstrlenA(mbcsBuffer);
  1799.  
  1800.     // ensure the supplied buffer is big enough
  1801.     int nRequiredSize = ::MultiByteToWideChar(CP_ACP, 0, mbcsBuffer, nBufferLen + 1, 0, 0);
  1802.     if (uSize < (DWORD) nRequiredSize)
  1803.         return (DWORD) nRequiredSize;
  1804.  
  1805.     ::MultiByteToWideChar(CP_ACP, 0, mbcsBuffer, nBufferLen + 1, lpBuffer, uSize);
  1806.     return nRequiredSize - 1; // do not include the NULL
  1807. }
  1808.  
  1809. UINT WINAPI
  1810. GetTempFileNameW(
  1811.     IN LPCWSTR lpPathName,
  1812.     IN LPCWSTR lpPrefixString,
  1813.     IN UINT uUnique,
  1814.     OUT LPWSTR lpTempFileName
  1815.     )
  1816. {
  1817.     CMbcsBuffer mbcsPathName;
  1818.     if (!mbcsPathName.FromUnicode(lpPathName))
  1819.         return 0;
  1820.  
  1821.     CMbcsBuffer mbcsPrefixString;
  1822.     if (!mbcsPrefixString.FromUnicode(lpPrefixString))
  1823.         return 0;
  1824.  
  1825.     char szTempFileName[MAX_PATH];
  1826.     UINT uiResult = ::GetTempFileNameA(mbcsPathName, mbcsPrefixString, uUnique, szTempFileName);
  1827.     if (uiResult == 0)
  1828.         return 0;
  1829.  
  1830.     ::MultiByteToWideChar(CP_ACP, 0, szTempFileName, -1, lpTempFileName, MAX_PATH);
  1831.     return uiResult;
  1832. }
  1833. #endif
  1834. extern "C" DWORD WINAPI
  1835. zGetTempPathW(
  1836.     IN DWORD uSize,
  1837.     OUT LPWSTR lpBuffer
  1838.     )
  1839. {
  1840.     DWORD dwResult = 0;
  1841.     CMbcsBuffer mbcsBuffer;
  1842.     do {
  1843.         if (dwResult > (DWORD) mbcsBuffer.BufferSize()) {
  1844.             if (!mbcsBuffer.SetCapacity((int) dwResult))
  1845.                 return 0;
  1846.         }
  1847.  
  1848.         dwResult = ::GetTempPathA((DWORD) mbcsBuffer.BufferSize(), mbcsBuffer);
  1849.         if (!dwResult)
  1850.             return 0;
  1851.     }
  1852.     while (dwResult > (DWORD) mbcsBuffer.BufferSize());
  1853.     int nBufferLen = ::lstrlenA(mbcsBuffer);
  1854.  
  1855.     // ensure the supplied buffer is big enough
  1856.     int nRequiredSize = ::MultiByteToWideChar(CP_ACP, 0, mbcsBuffer, nBufferLen + 1, 0, 0);
  1857.     if (uSize < (DWORD) nRequiredSize)
  1858.         return (DWORD) nRequiredSize;
  1859.  
  1860.     ::MultiByteToWideChar(CP_ACP, 0, mbcsBuffer, nBufferLen + 1, lpBuffer, uSize);
  1861.     return nRequiredSize - 1; // do not include the NULL
  1862. }
  1863.  
  1864. // GetTimeFormatW
  1865. // GetVersionExW
  1866. /* TODO : GetVolumeInformationW */
  1867. extern "C" BOOL WINAPI zGetVolumeInformationW(
  1868.   __in_opt   LPCWSTR lpRootPathName,
  1869.   __out      LPWSTR lpVolumeNameBuffer,
  1870.   __in       DWORD nVolumeNameSize,
  1871.   __out_opt  LPDWORD lpVolumeSerialNumber,
  1872.   __out_opt  LPDWORD lpMaximumComponentLength,
  1873.   __out_opt  LPDWORD lpFileSystemFlags,
  1874.   __out      LPWSTR lpFileSystemNameBuffer,
  1875.   __in       DWORD nFileSystemNameSize
  1876.     )
  1877. {      
  1878.     CMbcsBuffer mbcsRoot;
  1879.     if (!mbcsRoot.FromUnicode(lpRootPathName))
  1880.         return FALSE;
  1881.  
  1882.     BOOL Result;// = false;
  1883.     CMbcsBuffer mbcsVolumeNameBuffer;
  1884.     if (!mbcsVolumeNameBuffer.SetCapacity((int) nVolumeNameSize))
  1885.         return 0;            
  1886.     CMbcsBuffer mbcsFileSystemNameBuffer;
  1887.     if (!mbcsFileSystemNameBuffer.SetCapacity((int) nFileSystemNameSize))
  1888.         return 0;
  1889.  
  1890.     Result = ::GetVolumeInformationA(mbcsRoot,
  1891.         mbcsVolumeNameBuffer, (DWORD) mbcsVolumeNameBuffer.BufferSize(),
  1892.         lpVolumeSerialNumber, lpMaximumComponentLength, lpFileSystemFlags,
  1893.         mbcsFileSystemNameBuffer, (DWORD) mbcsFileSystemNameBuffer.BufferSize());
  1894.     if (!Result)
  1895.         return false;
  1896.  
  1897.     int nLen = ::lstrlenA(mbcsVolumeNameBuffer);
  1898.     ::MultiByteToWideChar(CP_ACP, 0, mbcsVolumeNameBuffer, nLen + 1,
  1899.             lpVolumeNameBuffer, nVolumeNameSize);  
  1900.     nLen = ::lstrlenA(mbcsFileSystemNameBuffer);
  1901.     ::MultiByteToWideChar(CP_ACP, 0, mbcsFileSystemNameBuffer, nLen + 1,
  1902.             lpFileSystemNameBuffer, nFileSystemNameSize);
  1903.     return true;
  1904. }
  1905.  
  1906. #if 0
  1907. UINT WINAPI
  1908. GetWindowsDirectoryW(
  1909.     OUT LPWSTR lpBuffer,
  1910.     IN UINT uSize
  1911.     )
  1912. {
  1913.     DWORD dwResult = 0;
  1914.     CMbcsBuffer mbcsBuffer;
  1915.     do {
  1916.         if (dwResult > (DWORD) mbcsBuffer.BufferSize()) {
  1917.             if (!mbcsBuffer.SetCapacity((int) dwResult))
  1918.                 return 0;
  1919.         }
  1920.  
  1921.         dwResult = ::GetWindowsDirectoryA(mbcsBuffer, (DWORD) mbcsBuffer.BufferSize());
  1922.         if (!dwResult)
  1923.             return 0;
  1924.     }
  1925.     while (dwResult > (DWORD) mbcsBuffer.BufferSize());
  1926.     int nBufferLen = ::lstrlenA(mbcsBuffer);
  1927.  
  1928.     // ensure the supplied buffer is big enough
  1929.     int nRequiredSize = ::MultiByteToWideChar(CP_ACP, 0, mbcsBuffer, nBufferLen + 1, 0, 0);
  1930.     if (uSize < (DWORD) nRequiredSize)
  1931.         return (DWORD) nRequiredSize;
  1932.  
  1933.     ::MultiByteToWideChar(CP_ACP, 0, mbcsBuffer, nBufferLen + 1, lpBuffer, uSize);
  1934.     return nRequiredSize - 1; // do not include the NULL
  1935. }
  1936.  
  1937. ATOM WINAPI
  1938. GlobalAddAtomW(
  1939.     IN LPCWSTR lpString
  1940.     )
  1941. {
  1942.     CMbcsBuffer mbcsString;
  1943.     if (!mbcsString.FromUnicode(lpString))
  1944.         return 0;
  1945.  
  1946.     return ::GlobalAddAtomA(mbcsString);
  1947. }
  1948.  
  1949. ATOM WINAPI
  1950. GlobalFindAtomW(
  1951.     IN LPCWSTR lpString
  1952.     )
  1953. {
  1954.     CMbcsBuffer mbcsString;
  1955.     if (!mbcsString.FromUnicode(lpString))
  1956.         return 0;
  1957.  
  1958.     return ::GlobalFindAtomA(mbcsString);
  1959. }
  1960.  
  1961. UINT
  1962. WINAPI
  1963. GlobalGetAtomNameW(
  1964.     IN ATOM nAtom,
  1965.     OUT LPWSTR lpBuffer,
  1966.     IN int nSize
  1967.     )
  1968. {
  1969.     CMbcsBuffer mbcsBuffer;
  1970.     UINT uiLen = ::GlobalGetAtomNameA(nAtom, mbcsBuffer, mbcsBuffer.BufferSize());
  1971.     if (!uiLen)
  1972.         return 0;
  1973.  
  1974.     int nLen = ::MultiByteToWideChar(CP_ACP, 0, mbcsBuffer, uiLen + 1, lpBuffer, nSize);
  1975.     if (!nLen) {
  1976.         SetLastError(ERROR_INSUFFICIENT_BUFFER);
  1977.         return 0;
  1978.     }
  1979.  
  1980.     return (UINT) (nLen - 1);
  1981. }
  1982.  
  1983. BOOL WINAPI
  1984. IsBadStringPtrW(
  1985.     IN LPCWSTR lpsz,
  1986.     IN UINT_PTR ucchMax
  1987.     )
  1988. {
  1989.     if (ucchMax == 0)
  1990.         return 0;
  1991.  
  1992.     //Note: slow because we call the IsBadReadPtr function
  1993.     // once for every character before we examine the character,
  1994.     // but I can't see another way to do this.
  1995.     do
  1996.     {
  1997.         if (::IsBadReadPtr(lpsz, sizeof(wchar_t)))
  1998.             return 1;
  1999.     }
  2000.     while (*lpsz++ && --ucchMax > 0);
  2001.  
  2002.     return 0;
  2003. }
  2004.  
  2005. //TODO: MSLU adds support for CP_UTF7 and CP_UTF8
  2006. BOOL WINAPI
  2007. OCOW_IsValidCodePage(
  2008.     IN UINT  CodePage
  2009.     )
  2010. {
  2011.     return ::IsValidCodePage(CodePage);
  2012. }
  2013. #endif
  2014. //TODO: MSLU adds support for CP_UTF7 and CP_UTF8
  2015. extern "C" int WINAPI
  2016. zLCMapStringW(
  2017.     IN LCID     Locale,
  2018.     IN DWORD    dwMapFlags,
  2019.     IN LPCWSTR  lpSrcStr,
  2020.     IN int      cchSrc,
  2021.     OUT LPWSTR  lpDestStr,
  2022.     IN int      cchDest
  2023.     )
  2024. {
  2025.     CMbcsBuffer mbcsString;
  2026.     if (!mbcsString.FromUnicode(lpSrcStr, cchSrc))
  2027.         return 0;
  2028.  
  2029.     // get the buffer size required
  2030.     int nRequired = ::LCMapStringA(Locale, dwMapFlags,
  2031.         mbcsString, mbcsString.Length(), 0, 0);
  2032.     if (nRequired == 0)
  2033.         return 0;
  2034.     if ((dwMapFlags & LCMAP_SORTKEY) && (cchDest == 0))
  2035.         return nRequired;
  2036.  
  2037.     CMbcsBuffer mbcsDest;
  2038.     if (!mbcsDest.SetCapacity(nRequired))
  2039.         return 0;
  2040.  
  2041.     nRequired = ::LCMapStringA(Locale, dwMapFlags,
  2042.         mbcsString, mbcsString.Length(), mbcsDest, mbcsDest.BufferSize());
  2043.     if (nRequired == 0)
  2044.         return 0;
  2045.  
  2046.     if (dwMapFlags & LCMAP_SORTKEY) {
  2047.         if (cchDest < nRequired) {
  2048.             SetLastError(ERROR_INSUFFICIENT_BUFFER);
  2049.             return 0;
  2050.         }
  2051.         ::CopyMemory(lpDestStr, mbcsDest.get(), nRequired);
  2052.         return nRequired;
  2053.     }
  2054.  
  2055.     return ::MultiByteToWideChar(CP_ACP, 0, mbcsDest, nRequired, lpDestStr, cchDest);
  2056. }
  2057. #if 0
  2058. HMODULE WINAPI
  2059. LoadLibraryExW(
  2060.     IN LPCWSTR lpLibFileName,
  2061.     IN HANDLE hFile,
  2062.     IN DWORD dwFlags
  2063.     )
  2064. {
  2065.     CMbcsBuffer mbcsLibFileName;
  2066.     if (!mbcsLibFileName.FromUnicode(lpLibFileName))
  2067.         return NULL;
  2068.  
  2069.     return ::LoadLibraryExA(mbcsLibFileName, hFile, dwFlags);
  2070. }
  2071.  
  2072. HMODULE WINAPI
  2073. zLoadLibraryW(
  2074.     IN LPCWSTR lpLibFileName
  2075.     )
  2076. {
  2077.     CMbcsBuffer mbcsLibFileName;
  2078.     if (!mbcsLibFileName.FromUnicode(lpLibFileName))
  2079.         return NULL;
  2080.  
  2081.     return ::LoadLibraryA(mbcsLibFileName);
  2082. }
  2083. #endif
  2084. #if 0
  2085. extern "C" BOOL WINAPI
  2086. zMoveFileW(
  2087.     IN LPCWSTR lpExistingFileName,
  2088.     IN LPCWSTR lpNewFileName
  2089.     )
  2090. {
  2091.     CMbcsBuffer mbcsExistingFileName;
  2092.     if (!mbcsExistingFileName.FromUnicode(lpExistingFileName))
  2093.         return FALSE;
  2094.  
  2095.     CMbcsBuffer mbcsNewFileName;
  2096.     if (!mbcsNewFileName.FromUnicode(lpNewFileName))
  2097.         return FALSE;
  2098.  
  2099.     return ::MoveFileA(mbcsExistingFileName, mbcsNewFileName);
  2100. }
  2101. #endif
  2102. extern "C" BOOL WINAPI
  2103. zMoveFileWithProgressW(
  2104.     IN  LPCTSTR lpExistingFileName,
  2105.     IN  LPCTSTR lpNewFileName,
  2106.     IN  LPPROGRESS_ROUTINE lpProgressRoutine,
  2107.     IN  LPVOID lpData,
  2108.     IN  DWORD dwFlags
  2109. )
  2110. {
  2111. #pragma argsused
  2112.     CMbcsBuffer mbcsExistingFileName;
  2113.     if (!mbcsExistingFileName.FromUnicode(lpExistingFileName))
  2114.         return FALSE;
  2115.  
  2116.     CMbcsBuffer mbcsNewFileName;
  2117.     if (!mbcsNewFileName.FromUnicode(lpNewFileName))
  2118.         return FALSE;
  2119.  
  2120.     if (dwFlags & MOVEFILE_REPLACE_EXISTING)
  2121.     {
  2122.         WIN32_FIND_DATAA FindFileData;
  2123.         HANDLE hFind;
  2124.         hFind = FindFirstFileA(mbcsNewFileName, &FindFileData);
  2125.         if (hFind != INVALID_HANDLE_VALUE)
  2126.        {
  2127.             bool repass = FindFileData.dwFileAttributes & 0;
  2128.             FindClose(hFind);
  2129.             if (!repass)
  2130.             {
  2131.                 // delete file    
  2132.                 if (!DeleteFileA(mbcsNewFileName))
  2133.                     return false;   // Can't erase file--give up
  2134.                 Sleep(10);
  2135.             }
  2136.         }
  2137.     }
  2138.     return ::MoveFileA(mbcsExistingFileName, mbcsNewFileName);
  2139. }
  2140. #if 0
  2141. //TODO: MSLU adds support for CP_UTF7 and CP_UTF8 to Windows 95
  2142. extern "C" int WINAPI
  2143. OCOW_MultiByteToWideChar(
  2144.     IN UINT     CodePage,
  2145.     IN DWORD    dwFlags,
  2146.     IN LPCSTR   lpMultiByteStr,
  2147.     IN int      cbMultiByte,
  2148.     OUT LPWSTR  lpWideCharStr,
  2149.     IN int      cchWideChar
  2150.     )
  2151. {
  2152.     return ::MultiByteToWideChar(CodePage, dwFlags,
  2153.         lpMultiByteStr, cbMultiByte, lpWideCharStr, cchWideChar);
  2154. }
  2155. #endif
  2156. #if 0
  2157. HANDLE WINAPI
  2158. OpenEventW(
  2159.     IN DWORD dwDesiredAccess,
  2160.     IN BOOL bInheritHandle,
  2161.     IN LPCWSTR lpName
  2162.     )
  2163. {
  2164.     CMbcsBuffer mbcsName;
  2165.     if (!mbcsName.FromUnicode(lpName))
  2166.         return NULL;
  2167.  
  2168.     return ::OpenEventA(dwDesiredAccess, bInheritHandle, mbcsName);
  2169. }
  2170.  
  2171. HANDLE WINAPI
  2172. OpenFileMappingW(
  2173.     IN DWORD dwDesiredAccess,
  2174.     IN BOOL bInheritHandle,
  2175.     IN LPCWSTR lpName
  2176.     )
  2177. {
  2178.     CMbcsBuffer mbcsName;
  2179.     if (!mbcsName.FromUnicode(lpName))
  2180.         return NULL;
  2181.  
  2182.     return ::OpenFileMappingA(dwDesiredAccess, bInheritHandle, mbcsName);
  2183. }
  2184.  
  2185. HANDLE WINAPI
  2186. OpenMutexW(
  2187.     IN DWORD dwDesiredAccess,
  2188.     IN BOOL bInheritHandle,
  2189.     IN LPCWSTR lpName
  2190.     )
  2191. {
  2192.     CMbcsBuffer mbcsName;
  2193.     if (!mbcsName.FromUnicode(lpName))
  2194.         return NULL;
  2195.  
  2196.     return ::OpenMutexA(dwDesiredAccess, bInheritHandle, mbcsName);
  2197. }
  2198.  
  2199. HANDLE WINAPI
  2200. OpenSemaphoreW(
  2201.     IN DWORD dwDesiredAccess,
  2202.     IN BOOL bInheritHandle,
  2203.     IN LPCWSTR lpName
  2204.     )
  2205. {
  2206.     CMbcsBuffer mbcsName;
  2207.     if (!mbcsName.FromUnicode(lpName))
  2208.         return NULL;
  2209.  
  2210.     return ::OpenSemaphoreA(dwDesiredAccess, bInheritHandle, mbcsName);
  2211. }
  2212.  
  2213. typedef HANDLE (WINAPI *fpOpenWaitableTimerA)(
  2214.     IN DWORD dwDesiredAccess,
  2215.     IN BOOL bInheritHandle,
  2216.     IN LPCSTR lpTimerName
  2217.     );
  2218.  
  2219. HANDLE WINAPI
  2220. OpenWaitableTimerW(
  2221.     IN DWORD dwDesiredAccess,
  2222.     IN BOOL bInheritHandle,
  2223.     IN LPCWSTR lpTimerName
  2224.     )
  2225. {
  2226.     static fpOpenWaitableTimerA pOpenWaitableTimerA =
  2227.         (fpOpenWaitableTimerA) ::GetProcAddress(
  2228.             ::GetModuleHandleA("kernel32.dll"), "OpenWaitableTimerA");
  2229.     if (!pOpenWaitableTimerA) {
  2230.         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  2231.         return NULL;
  2232.     }
  2233.  
  2234.     CMbcsBuffer mbcsTimerName;
  2235.     if (!mbcsTimerName.FromUnicode(lpTimerName))
  2236.         return NULL;
  2237.  
  2238.     return pOpenWaitableTimerA(dwDesiredAccess, bInheritHandle, mbcsTimerName);
  2239. }
  2240. #endif
  2241. extern "C" VOID WINAPI
  2242. zOutputDebugStringW(
  2243.     IN LPCWSTR lpOutputString
  2244.     )
  2245. {
  2246.     CMbcsBuffer mbcsOutputString;
  2247.     if (!mbcsOutputString.FromUnicode(lpOutputString))
  2248.         return;
  2249.  
  2250.     ::OutputDebugStringA(mbcsOutputString);
  2251. }
  2252.  
  2253. // PeekConsoleInputW
  2254. // QueryDosDeviceW
  2255. // ReadConsoleInputW
  2256. // ReadConsoleOutputCharacterW
  2257. // ReadConsoleOutputW
  2258. // ReadConsoleW
  2259.  
  2260. extern "C" BOOL WINAPI
  2261. zRemoveDirectoryW(
  2262.     IN LPCWSTR lpPathName
  2263.     )
  2264. {
  2265.     CMbcsBuffer mbcsPathName;
  2266.     if (!mbcsPathName.FromUnicode(lpPathName))
  2267.         return FALSE;
  2268.  
  2269.     return ::RemoveDirectoryA(mbcsPathName);
  2270. }
  2271.  
  2272. // ScrollConsoleScreenBufferW
  2273. // SearchPathW
  2274. // SetCalendarInfoW
  2275. #if 0
  2276. BOOL WINAPI
  2277. SetComputerNameW(
  2278.     IN LPCWSTR lpComputerName
  2279.     )
  2280. {
  2281.     // ensure that the computer name is valid as per NT guidelines,
  2282.     // we don't coerce the characters here
  2283.     const wchar_t * pTemp = lpComputerName;
  2284.     for (wchar_t c = *pTemp; c; c = *(++pTemp)) {
  2285.         if ((c >= L'A' && c <= L'Z') ||
  2286.             (c >= L'a' && c <= L'z') ||
  2287.             (c >= L'0' && c <= L'9')) {
  2288.             continue;
  2289.         }
  2290.         switch (c) {
  2291.             case L'!': case L'@': case L'#': case L'$': case L'%': case L'^':
  2292.             case L'&': case L')': case L'(': case L'.': case L'-': case L'_':
  2293.             case L'{': case L'}': case L'~': case L'\'':
  2294.                 break;
  2295.             default:
  2296.                 SetLastError(ERROR_INVALID_PARAMETER);
  2297.                 return FALSE;
  2298.         }
  2299.     }
  2300.  
  2301.     CMbcsBuffer mbcsComputerName;
  2302.     if (!mbcsComputerName.FromUnicode(lpComputerName))
  2303.         return FALSE;
  2304.  
  2305.     return ::SetComputerNameA(mbcsComputerName);
  2306. }
  2307.  
  2308. BOOL WINAPI
  2309. SetConsoleTitleW(
  2310.     IN LPCWSTR lpConsoleTitle
  2311.     )
  2312. {
  2313.     CMbcsBuffer mbcsConsoleTitle;
  2314.     if (!mbcsConsoleTitle.FromUnicode(lpConsoleTitle))
  2315.         return FALSE;
  2316.  
  2317.     return ::SetConsoleTitleA(mbcsConsoleTitle);
  2318. }
  2319.  
  2320. BOOL WINAPI
  2321. SetCurrentDirectoryW(
  2322.     IN LPCWSTR lpPathName
  2323.     )
  2324. {
  2325.     CMbcsBuffer mbcsPathName;
  2326.     if (!mbcsPathName.FromUnicode(lpPathName))
  2327.         return FALSE;
  2328.  
  2329.     return ::SetCurrentDirectoryA(mbcsPathName);
  2330. }
  2331.  
  2332. // SetDefaultCommConfigW
  2333.  
  2334. BOOL WINAPI
  2335. SetEnvironmentVariableW(
  2336.     IN LPCWSTR lpName,
  2337.     IN LPCWSTR lpValue
  2338.     )
  2339. {
  2340.     CMbcsBuffer mbcsName;
  2341.     if (!mbcsName.FromUnicode(lpName))
  2342.         return FALSE;
  2343.  
  2344.     CMbcsBuffer mbcsValue;
  2345.     if (!mbcsValue.FromUnicode(lpValue))
  2346.         return FALSE;
  2347.  
  2348.     return ::SetEnvironmentVariableA(mbcsName, mbcsValue);
  2349. }
  2350. #endif
  2351. extern "C" BOOL WINAPI
  2352. zSetFileAttributesW(
  2353.     IN LPCWSTR lpFileName,
  2354.     IN DWORD dwFileAttributes
  2355.     )
  2356. {
  2357.     CMbcsBuffer mbcsFileName;
  2358.     if (!mbcsFileName.FromUnicode(lpFileName))
  2359.         return FALSE;
  2360.  
  2361.     return ::SetFileAttributesA(mbcsFileName, dwFileAttributes);
  2362. }
  2363.  
  2364. // SetLocaleInfoW
  2365. #if 0
  2366. BOOL WINAPI
  2367. SetVolumeLabelW(
  2368.     IN LPCWSTR lpRootPathName,
  2369.     IN LPCWSTR lpVolumeName
  2370.     )
  2371. {
  2372.     CMbcsBuffer mbcsRootPathName;
  2373.     if (!mbcsRootPathName.FromUnicode(lpRootPathName))
  2374.         return FALSE;
  2375.  
  2376.     CMbcsBuffer mbcsVolumeName;
  2377.     if (!mbcsVolumeName.FromUnicode(lpVolumeName))
  2378.         return FALSE;
  2379.  
  2380.     return ::SetVolumeLabelA(mbcsRootPathName, mbcsVolumeName);
  2381. }
  2382. #endif
  2383. // UpdateResourceA
  2384. // UpdateResourceW
  2385. // WaitNamedPipeW
  2386. #if 0
  2387. //TODO: MSLU adds support for CP_UTF7 and CP_UTF8 to Windows 95
  2388. extern "C" int WINAPI
  2389. OCOW_WideCharToMultiByte(
  2390.     IN UINT     CodePage,
  2391.     IN DWORD    dwFlags,
  2392.     IN LPCWSTR  lpWideCharStr,
  2393.     IN int      cchWideChar,
  2394.     OUT LPSTR   lpMultiByteStr,
  2395.     IN int      cbMultiByte,
  2396.     IN LPCSTR   lpDefaultChar,
  2397.     OUT LPBOOL  lpUsedDefaultChar)
  2398. {
  2399.     return ::WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar,
  2400.         lpMultiByteStr, cbMultiByte, lpDefaultChar, lpUsedDefaultChar);
  2401. }
  2402. #endif
  2403. // WriteConsoleInputW
  2404. // WriteConsoleOutputCharacterW
  2405. // WriteConsoleOutputW
  2406. // WriteConsoleW
  2407. // WritePrivateProfileSectionW
  2408. // WritePrivateProfileStringW
  2409. // WritePrivateProfileStructW
  2410. // WriteProfileSectionW
  2411. // WriteProfileStringW
  2412. #if 0
  2413. LPWSTR WINAPI
  2414. lstrcatW(
  2415.     IN OUT LPWSTR lpString1,
  2416.     IN LPCWSTR lpString2
  2417.     )
  2418. {
  2419.     if (!lpString1 || !lpString2)
  2420.         return NULL;
  2421.     if (!*lpString2)
  2422.         return lpString1;
  2423.  
  2424.     LPWSTR lpTemp = lpString1;
  2425.     while (*lpTemp)
  2426.         ++lpTemp;
  2427.     while (*lpString2)
  2428.         *lpTemp++ = *lpString2++;
  2429.     *lpTemp = 0;
  2430.  
  2431.     return lpString1;
  2432. }
  2433.  
  2434. // lstrcmpW
  2435. // lstrcmpiW
  2436.  
  2437. LPWSTR
  2438. WINAPI
  2439. lstrcpyW(
  2440.     OUT LPWSTR lpString1,
  2441.     IN LPCWSTR lpString2
  2442.     )
  2443. {
  2444.     if (!lpString1 || !lpString2)
  2445.         return NULL;
  2446.  
  2447.     LPWSTR lpTemp = lpString1;
  2448.     while (*lpString2)
  2449.         *lpTemp++ = *lpString2++;
  2450.     *lpTemp = 0;
  2451.  
  2452.     return lpString1;
  2453. }
  2454.  
  2455. LPWSTR WINAPI
  2456. lstrcpynW(
  2457.     OUT LPWSTR lpString1,
  2458.     IN LPCWSTR lpString2,
  2459.     IN int iMaxLength
  2460.     )
  2461. {
  2462.     if (!lpString1 || !lpString2)
  2463.         return NULL;
  2464.     if (iMaxLength < 1)
  2465.         return lpString1;
  2466.  
  2467.     LPWSTR lpTemp = lpString1;
  2468.     while (*lpString2 && iMaxLength-- > 1)
  2469.         *lpTemp++ = *lpString2++;
  2470.     *lpTemp = 0;
  2471.  
  2472.     return lpString1;
  2473. }
  2474.  
  2475. int WINAPI
  2476. OCOW_lstrlenW(
  2477.     IN LPCWSTR lpString
  2478.     )
  2479. {
  2480.     int len = 0;
  2481.     while (*lpString++)
  2482.         ++len;
  2483.     return len;
  2484. }
  2485. #endif  
  2486. extern "C" int WINAPI
  2487. zlstrlenW(
  2488.     IN LPCWSTR lpString
  2489.     )
  2490. {
  2491.     int len = 0;
  2492.     while (*lpString++)
  2493.         ++len;
  2494.     return len;
  2495. }
  2496.  
  2497.  
  2498. #endif
  2499.