Subversion Repositories autosfx

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 daniel-mar 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