Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

15253 lines
446 KiB

  1. ;;/*++++++++++++++++++++++++++++++++++++++++++++++++++
  2. ;;
  3. ;; Copyright (c) 2000-2001, Microsoft Corporation All rights reserved.
  4. ;;
  5. ;; Module Name:
  6. ;;
  7. ;; unicows.tpl
  8. ;;
  9. ;; Abstract:
  10. ;;
  11. ;; The 'Template' file that drives genthnk. It contains all of the functions to
  12. ;; handle out params and such -- anything not automatable by genthnk.
  13. ;;
  14. ;; Revision History:
  15. ;;
  16. ;; 7 Nov 2000 v-michka Created.
  17. ;;
  18. ;;-------------------------------------------------*/
  19. ; // This template is a [Code] template. It is expanded by genthnk once
  20. ; // via the -cTemplateName command-line option. Stuff inside the Begin=
  21. ; // End= section is C code or genthnk macros which are prefixed by an 'at' char.
  22. ; //
  23. [Code]
  24. TemplateName=UnicodeWrappers
  25. Begin=
  26. @NoFormat(
  27. /*++
  28. Copyright (c) 2000-2001, Microsoft Corporation All rights reserved.
  29. Module Name:
  30. Win9xU.c (Windows 9x Unicode wrapper functions)
  31. Abstract:
  32. Auto-generated file that contains the thunks.
  33. WARNING: Do not edit! This file is auto-generated by getthnk.
  34. See unicows.tpl if you want to make changes.
  35. Revision History:
  36. 7 Nov 2000 v-michka Created.
  37. --*/
  38. #include "precomp.h"
  39. // work around thick-skulled genthnk. It wants ApiName to expand to the
  40. // name of the original Ansi API. We want to call the Ansi API by
  41. // appending "A". So... from makefile.inc we generate a bunch of #defines
  42. // of the form:
  43. // #define AddAtomWA AddAtomA
  44. // then from the .tpl file we can use ApiNameA to generate AddAtomWA for
  45. // the AddAtomW API thunk and get it expanded to the right thing.
  46. #include "fixaw.h"
  47. // A few globals: set on startup and used everywhere thereafter
  48. // We init these vars with some nice defaults; they *will* be fixed later
  49. UINT g_acp = CP_ACP; // CP_ACP; it is faster to call with the actual cpg than the CP_ACP const
  50. UINT g_oemcp = CP_OEMCP; // CP_OEMCP; it is faster to call with the actual cpg than the CP_OEMCP const
  51. UINT g_mcs = 2; // The maximum character size (in bytes) of a character on CP_ACP
  52. DWORD g_dwVersion = 0x80000001; // The return from GetVersion, used many places
  53. // VSANSI comments:
  54. // Static buffers for GetClassInfo[Ex] to return the classname
  55. // and menuname in Unicode, when running on an Ansi system.
  56. // The contract of GetClassInfo is that it returns const ptrs
  57. // back to the class name and menu name. Unfortuntely, this
  58. // prevents us from translating these back from Ansi to Unicode,
  59. // without having some static buffers to use. Since we strongly
  60. // believe that the only people calling this are doing it just to
  61. // see if it succeeds or not, so they know whether the class is
  62. // already registered, we've willing to just have one set of
  63. // static buffers to use.
  64. // CAUTION: this will work as long as two threads don't call
  65. // GetClassInfo[Ex] at the same time!
  66. static WCHAR m_wzMenuName[256];
  67. static WCHAR m_wzClassName[256];
  68. // Similar buffers for the strings returned by GetStartupInfo
  69. // Note that these two buffers are not really hacks; on NT, there
  70. // is a permanent buffer set aside for the ANSI version of this
  71. // call, per process. So we are no worse for doing the same thing
  72. // here for Win9x.
  73. static WCHAR m_wzDesktop[256];
  74. static WCHAR m_wzTitle[256];
  75. // The Ver* APIs are not very helpful to us since we have no place
  76. // from which to alloc pointers to Unicode strings. Therefore, we
  77. // will add a small area to the front of any GetFileVersionInfoSize
  78. // call that we can use. Note that this means that the calls to
  79. // VerQueryValue will erase the data from earlier calls, but we can't
  80. // pull the memory out of our butt, either.
  81. #define VERINFO_BUFFER (MAX_PATH * sizeof(WCHAR))
  82. // For FormatMessageW:
  83. // We will support a max of 99 arguments, up to 1023 cch per arg
  84. #define MAXINSERTS 99
  85. #define CCHMAXPERINSERT 1023
  86. // Need a few intrinsics
  87. #pragma intrinsic (strlen, strcmp, memcpy)
  88. // We have no header file, so lets add forward declares for any Godot
  89. // function that is used by other functions
  90. BOOL __stdcall GodotExtTextOutW(HDC hdc,int X,int Y,UINT fuOptions,const LPRECT lprc,LPCWSTR lpString,UINT cbCount,const PINT lpDx);
  91. HRSRC __stdcall GodotFindResourceExW(HMODULE hModule, LPCWSTR lpType, LPCWSTR lpName, WORD wLanguage);
  92. BOOL __stdcall GodotGetCharWidthW(HDC hdc,UINT iFirstChar,UINT iLastChar,LPINT lpBuffer);
  93. BOOL __stdcall GodotGetMonitorInfoW(HMONITOR hMonitor, LPMONITORINFO lpmi);
  94. BOOL __stdcall GodotIsClipboardFormatAvailable(UINT format);
  95. int __stdcall GodotwvsprintfW(LPWSTR lpOut, LPCWSTR lpFmt, va_list arglist);
  96. // Functions we dynamically link to since they might not exist on all
  97. // platforms that Godot runs upon. First the typdefs, then the function
  98. // pointers themselves will follow.
  99. typedef LONG (__stdcall *PFNcdsea) (LPCSTR, LPDEVMODEA, HWND, DWORD, LPVOID);
  100. typedef BOOL (__stdcall *PFNcfea) (LPCSTR, LPCSTR, LPPROGRESS_ROUTINE, LPVOID, LPBOOL, DWORD);
  101. typedef HRESULT (__stdcall *PFNcsapa) (HWND, LPCSTR, LONG, const IID *, void **);
  102. typedef HANDLE (__stdcall *PFNcwta) (LPSECURITY_ATTRIBUTES, BOOL, LPCSTR);
  103. typedef BOOL (__stdcall *PFNeciea) (CALINFO_ENUMPROCEXA, LCID, CALID, CALTYPE);
  104. typedef BOOL (__stdcall *PFNedfea) (DATEFMT_ENUMPROCEXA, LCID, DWORD);
  105. typedef BOOL (__stdcall *PFNedda) (LPCSTR, DWORD, PDISPLAY_DEVICEA, DWORD);
  106. typedef BOOL (__stdcall *PFNedsea) (LPCSTR, DWORD, LPDEVMODEA, DWORD);
  107. typedef BOOL (__stdcall *PFNgatia) (HWND, int, PALTTABINFO, LPSTR, UINT);
  108. typedef BOOL (__stdcall *PFNgcia) (LCID, CALID, CALTYPE, LPSTR, int, LPDWORD);
  109. typedef BOOL (__stdcall *PFNgciea) (UINT, DWORD, LPCPINFOEXA);
  110. typedef BOOL (__stdcall *PFNgchpa) (LPHW_PROFILE_INFOA);
  111. typedef BOOL (__stdcall *PFNgdfsea) (LPCSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER);
  112. typedef BOOL (__stdcall *PFNgfnaea) (LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
  113. typedef BOOL (__stdcall *PFNglpna) (LPCSTR, LPSTR, DWORD);
  114. typedef BOOL (__stdcall *PFNgmia) (HMONITOR, LPMONITORINFO);
  115. typedef HRESULT (__stdcall *PFNrgta) (DWORD, LPSTR, UINT);
  116. typedef HRESULT (__stdcall *PFNgsta) (DWORD, LPSTR, UINT);
  117. typedef UINT (__stdcall *PFNgwmfna) (HWND, LPSTR, UINT);
  118. typedef BOOL (__stdcall *pfnIDRA) (LPCSTR, LPQOCINFO);
  119. typedef HANDLE (__stdcall *PFNowta) (DWORD, BOOL, LPCSTR);
  120. typedef DWORD (__stdcall *pfnRCN) (HRASCONN, HANDLE, DWORD);
  121. typedef DWORD (__stdcall *pfnRCPE) (HWND, LPCSTR);
  122. typedef DWORD (__stdcall *pfnRDE) (LPCSTR, LPCSTR);
  123. typedef DWORD (__stdcall *pfnRDSE) (LPCSTR, LPCSTR, DWORD);
  124. typedef DWORD (__stdcall *pfnRD) (LPRASDIALEXTENSIONS, LPCSTR, LPRASDIALPARAMSA, DWORD, LPVOID, LPHRASCONN);
  125. typedef DWORD (__stdcall *pfnREPE) (HWND, LPCSTR, LPCSTR);
  126. typedef DWORD (__stdcall *pfnREC) (struct tagRASCONNA * , LPDWORD, LPDWORD);
  127. typedef DWORD (__stdcall *pfnRED) (LPRASDEVINFOA, LPDWORD, LPDWORD);
  128. typedef DWORD (__stdcall *pfnREE) (LPCSTR, LPCSTR, LPRASENTRYNAMEA, LPDWORD, LPDWORD);
  129. typedef DWORD (__stdcall *pfnRGCS) (HRASCONN, LPRASCONNSTATUSA);
  130. typedef DWORD (__stdcall *pfnRGEDP) (LPCSTR, LPRASDIALPARAMSA, LPBOOL);
  131. typedef DWORD (__stdcall *pfnRGEP) (LPCSTR, LPCSTR, LPRASENTRYA, LPDWORD, LPBYTE, LPDWORD);
  132. typedef DWORD (__stdcall *pfnRGES) (UINT, LPSTR, DWORD);
  133. typedef DWORD (__stdcall *pfnRHU) (HRASCONN);
  134. typedef DWORD (__stdcall *pfnRRE) (LPCSTR, LPCSTR, LPCSTR);
  135. typedef DWORD (__stdcall *pfnRSEDP) (LPCSTR, LPRASDIALPARAMSA, BOOL);
  136. typedef DWORD (__stdcall *pfnRSEP) (LPCSTR, LPCSTR, LPRASENTRYA, DWORD, LPBYTE, DWORD);
  137. typedef DWORD (__stdcall *pfnRSSEP) (LPCSTR, LPCSTR, DWORD, LPRASSUBENTRYA, DWORD, LPBYTE, DWORD);
  138. typedef DWORD (__stdcall *pfnRVEN) (LPCSTR, LPCSTR);
  139. typedef HDEVNOTIFY (__stdcall *PFNrdna) (HANDLE, LPVOID, DWORD);
  140. typedef BOOL (__stdcall *PFNscia) (LCID, CALID, CALTYPE, LPCSTR);
  141. static PFNcdsea s_pfnChangeDisplaySettingsExA;
  142. static PFNcfea s_pfnCopyFileExA;
  143. static PFNcsapa s_pfnCreateStdAccessibleProxy;
  144. static PFNcwta s_pfnCreateWaitableTimerA;
  145. static PFNeciea s_pfnEnumCalendarInfoExA;
  146. static PFNedfea s_pfnEnumDateFormatsExA;
  147. static PFNedda s_pfnEnumDisplayDevicesA;
  148. static PFNedsea s_pfnEnumDisplaySettingsExA;
  149. static PFNgatia s_pfnGetAltTabInfoA;
  150. static PFNgcia s_pfnGetCalendarInfoA;
  151. static PFNgciea s_pfnGetCPInfoExA;
  152. static PFNgchpa s_pfnGetCurrentHwProfileA;
  153. static PFNgdfsea s_pfnGetDiskFreeSpaceExA;
  154. static PFNgfnaea s_pfnGetFileAttributesExA;
  155. static PFNglpna s_pfnGetLongPathNameA;
  156. static PFNgmia s_pfnGetMonitorInfoA;
  157. static PFNrgta s_pfnGetRoleTextA;
  158. static PFNgsta s_pfnGetStateTextA;
  159. static PFNgwmfna s_pfnGetWindowModuleFileNameA;
  160. static pfnIDRA s_pfnIsDestinationReachableA;
  161. static PFNowta s_pfnOpenWaitableTimerA;
  162. static pfnRCN s_pfnRasConnectionNotificationA;
  163. static pfnRCPE s_pfnRasCreatePhonebookEntryA;
  164. static pfnRDE s_pfnRasDeleteEntryA;
  165. static pfnRDSE s_pfnRasDeleteSubEntryA;
  166. static pfnRD s_pfnRasDialA;
  167. static pfnREPE s_pfnRasEditPhonebookEntryA;
  168. static pfnREC s_pfnRasEnumConnectionsA;
  169. static pfnRED s_pfnRasEnumDevicesA;
  170. static pfnREE s_pfnRasEnumEntriesA;
  171. static pfnRGCS s_pfnRasGetConnectStatusA;
  172. static pfnRGEDP s_pfnRasGetEntryDialParamsA;
  173. static pfnRGEP s_pfnRasGetEntryPropertiesA;
  174. static pfnRGES s_pfnRasGetErrorStringA;
  175. static pfnRHU s_pfnRasHangUpA;
  176. static pfnRRE s_pfnRasRenameEntryA;
  177. static pfnRSEDP s_pfnRasSetEntryDialParamsA;
  178. static pfnRSEP s_pfnRasSetEntryPropertiesA;
  179. static pfnRSSEP s_pfnRasSetSubEntryPropertiesA;
  180. static pfnRVEN s_pfnRasValidateEntryNameA;
  181. static PFNrdna s_pfnRegisterDeviceNotificationA;
  182. static PFNscia s_pfnSetCalendarInfoA;
  183. BOOL WINAPI
  184. DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
  185. {
  186. // Perform actions based on the reason for calling.
  187. switch(fdwReason)
  188. {
  189. case DLL_PROCESS_ATTACH:
  190. g_tls = TlsAlloc();
  191. if (g_tls==TLS_OUT_OF_INDEXES)
  192. {
  193. // We are gonna go no further, we NEED that slot!
  194. // CONSIDER: Let us succeeed, but maybe we could try again later?
  195. SetLastError(ERROR_MAX_THRDS_REACHED);
  196. return(FALSE);
  197. }
  198. // CONSIDER: Can't this raise a STATUS_NO_MEMORY exception?
  199. // Perhaps we need to handle this
  200. InitializeCriticalSection(&g_csThreads);
  201. InitializeCriticalSection(&g_csWnds);
  202. // Set up some global information used elsewhere. No InterlockedExchange
  203. // is needed for these globals since the code is only ever called once
  204. // per process, and calls to DllMain are serialized by the OS, anyway.
  205. g_acp = GetACP();
  206. g_oemcp = GetOEMCP();
  207. g_dwVersion = GetVersion();
  208. g_mcs = CbPerChOfCpg(g_acp);
  209. break;
  210. case DLL_THREAD_ATTACH:
  211. break;
  212. case DLL_THREAD_DETACH:
  213. // Any time we get this notification, make sure
  214. // we free up our resources. If all else fails
  215. // we will get it on process close, but why not
  216. // try to get it here?
  217. UninitThread();
  218. break;
  219. case DLL_PROCESS_DETACH:
  220. if(g_tls)
  221. {
  222. // Free up our resources, if any
  223. UninitAllThreads();
  224. // Clean up the TLS
  225. TlsFree(g_tls);
  226. }
  227. // free up our critical sections
  228. if(&g_csThreads)
  229. DeleteCriticalSection(&g_csThreads);
  230. if(&g_csWnds)
  231. DeleteCriticalSection(&g_csWnds);
  232. break;
  233. }
  234. return TRUE;
  235. UNREFERENCED_PARAMETER(hinstDLL);
  236. UNREFERENCED_PARAMETER(lpvReserved);
  237. }
  238. @Template(ApiWrapper)
  239. End=
  240. ; // These templates are [Types] templates. They are expanded whenever
  241. ; // an API argument type matches.
  242. ; // ArgName - name of the argument
  243. [Types]
  244. TypeName=LPWSTR
  245. Also=LPCWSTR
  246. IndLevel=0
  247. Direction=IN
  248. Locals=
  249. LPSTR @ArgNameAnsi;
  250. End=
  251. Precall=
  252. GODOT_TO_ACP_STACKALLOC(@ArgName, @ArgNameAnsi);
  253. #define @ArgName @ArgNameAnsi
  254. End=
  255. Postcall=
  256. #undef @ArgName
  257. End=
  258. ; //
  259. ; // This template is an [IFunc] template. It is expanded once for each API.
  260. ; // Macros:
  261. ; // ApiName - the name of the API
  262. ; // ArgList() - expands the contents for each argument to the API
  263. ; // ListCol - text formatting - makes a nice column
  264. ; // ArgMod - type modifier like const/volatile
  265. ; // ArgType - type of the argument
  266. ; // ArgName - name of the argument (genthnk will assign a name if the prototype didn't name the arg)
  267. ; // ArgMore() - expands iff there are more args after the current one
  268. ; // IfApiRet() - expands iff the return type of the API is non-void
  269. ; // ApiFnRet - return type of the API
  270. ; // Types() - expands any applicable parts of [Types] templates
  271. ; // IfApiCode() - expands any applicable parts of [EFunc] templates
  272. ; //
  273. [IFunc]
  274. TemplateName=ApiWrapper
  275. Begin=
  276. @ApiFnRet @ApiFnMod
  277. Godot@ApiName(@ArgList(@ListCol@ArgMod @ArgType @ArgName@ArgMore(,)))
  278. {
  279. // Begin locals
  280. @IfApiRet(@ApiFnRet RetVal;)
  281. @Types(Locals)
  282. @IfApiCode(Locals)
  283. // Begin precall
  284. @Types(Precall)
  285. @IfApiCode(Precall)
  286. // Call the 'A' version of the API
  287. @IfApiRet(RetVal=)@ApiNameA(@ArgList(@ListCol@ArgName@ArgMore(,)));
  288. // Begin postcall
  289. @Types(Postcall)
  290. @IfApiCode(Postcall)
  291. // Finished
  292. return @IfApiRet(RetVal);
  293. }
  294. End=
  295. [EFunc]
  296. TemplateName=AcquireCredentialsHandleW
  297. Begin=
  298. SECURITY_STATUS __stdcall
  299. GodotAcquireCredentialsHandleW( SEC_WCHAR SEC_FAR * pPrincipal,
  300. SEC_WCHAR SEC_FAR * pPackage,
  301. unsigned long int fCredentialUse,
  302. void * pvLogonId,
  303. void * pAuthData,
  304. SEC_GET_KEY_FN pGetKeyFn,
  305. void * pvGetKeyArgument,
  306. PCredHandle phCredential,
  307. PTimeStamp ptsExpiry
  308. )
  309. {
  310. // ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
  311. return(SEC_E_UNSUPPORTED_FUNCTION);
  312. }
  313. End=
  314. [EFunc]
  315. TemplateName=AddJobW
  316. Begin=
  317. BOOL __stdcall
  318. GodotAddJobW(HANDLE hPrinter, DWORD Level, LPBYTE pData, DWORD cbBuf, LPDWORD pcbNeeded)
  319. {
  320. // Begin locals
  321. BOOL RetVal;
  322. LPADDJOB_INFO_1A lpajia;
  323. LPADDJOB_INFO_1W lpaji;
  324. if(Level != 1)
  325. {
  326. SetLastError(ERROR_INVALID_PARAMETER);
  327. return(FALSE);
  328. }
  329. if(cbBuf == 0)
  330. SetLastError(ERROR_INVALID_USER_BUFFER);
  331. if((cbBuf == 0) || (cbBuf < (sizeof(ADDJOB_INFO_1W) + MAX_PATH * sizeof(WCHAR))))
  332. {
  333. if(pcbNeeded)
  334. *pcbNeeded = (sizeof(ADDJOB_INFO_1W) + MAX_PATH * sizeof(WCHAR));
  335. return(FALSE);
  336. }
  337. _STACKALLOC(sizeof(ADDJOB_INFO_1A) + (MAX_PATH * g_mcs), lpajia);
  338. if(lpajia==NULL)
  339. return(FALSE);
  340. ZeroMemory(lpajia, sizeof(ADDJOB_INFO_1A) + (MAX_PATH * g_mcs));
  341. RetVal=AddJobA(hPrinter, Level, (LPBYTE)lpajia, cbBuf, pcbNeeded);
  342. if(RetVal)
  343. {
  344. lpaji = (LPADDJOB_INFO_1W)pData;
  345. MultiByteToWideChar(g_acp, 0,
  346. lpajia->Path, MAX_PATH,
  347. (LPWSTR)(pData + sizeof(ADDJOB_INFO_1A)), MAX_PATH);
  348. lpaji->Path = (LPWSTR)(pData + sizeof(ADDJOB_INFO_1A));
  349. lpaji->JobId = lpajia->JobId;
  350. if(pcbNeeded)
  351. *pcbNeeded = (sizeof(ADDJOB_INFO_1W) + MAX_PATH * sizeof(WCHAR));
  352. }
  353. // Finished
  354. return RetVal;
  355. }
  356. End=
  357. [EFunc]
  358. TemplateName=AddMonitorW
  359. Begin=
  360. BOOL __stdcall
  361. GodotAddMonitorW(LPWSTR pName, DWORD Level, LPBYTE pMonitors)
  362. {
  363. if(Level != 2)
  364. {
  365. SetLastError(ERROR_INVALID_PARAMETER);
  366. return(FALSE);
  367. }
  368. else
  369. {
  370. LPSTR pNameAnsi;
  371. MONITOR_INFO_2A mia;
  372. LPMONITOR_INFO_2W lpmi;
  373. // Begin precall
  374. GODOT_TO_ACP_STACKALLOC(pName, pNameAnsi);
  375. if(!pNameAnsi && pName)
  376. {
  377. return(FALSE);
  378. }
  379. ZeroMemory(&mia, sizeof(MONITOR_INFO_2A));
  380. lpmi = (LPMONITOR_INFO_2W)pMonitors;
  381. GODOT_TO_ACP_STACKALLOC(lpmi->pName, mia.pName);
  382. GODOT_TO_ACP_STACKALLOC(lpmi->pEnvironment, mia.pEnvironment);
  383. GODOT_TO_ACP_STACKALLOC(lpmi->pDLLName, mia.pDLLName);
  384. if((!(mia.pName) && (lpmi->pName)) ||
  385. (!(mia.pEnvironment) && (lpmi->pEnvironment)) ||
  386. (!(mia.pDLLName) && (lpmi->pDLLName)))
  387. return(FALSE);
  388. return(AddMonitorA(pNameAnsi, Level, (LPBYTE)&mia));
  389. }
  390. }
  391. End=
  392. [EFunc]
  393. TemplateName=AddPortW
  394. Begin=
  395. BOOL __stdcall
  396. GodotAddPortW(LPWSTR pName, HWND hWnd, LPWSTR pMonitorName)
  397. {
  398. BOOL RetVal = FALSE;
  399. LPSTR pNameAnsi = NULL;
  400. LPSTR pMonitorNameAnsi = NULL;
  401. ALLOCRETURN arName = GodotToAcpOnHeap(pName, &pNameAnsi);
  402. ALLOCRETURN arMonitorName = GodotToAcpOnHeap(pMonitorName, &pMonitorNameAnsi);
  403. if(arName != arFailed && arMonitorName != arFailed)
  404. RetVal = AddPortA(pNameAnsi, hWnd, pMonitorNameAnsi);
  405. if(arName==arAlloc)
  406. GodotHeapFree(pNameAnsi);
  407. if(arMonitorName==arAlloc)
  408. GodotHeapFree(pMonitorName);
  409. if(arName == arFailed || arMonitorName == arFailed)
  410. SetLastError(ERROR_OUTOFMEMORY);
  411. return RetVal;
  412. }
  413. End=
  414. [EFunc]
  415. TemplateName=AddPrinterW
  416. Begin=
  417. HANDLE __stdcall
  418. GodotAddPrinterW(LPWSTR pName, DWORD Level, LPBYTE pPrinter)
  419. {
  420. LPSTR pNameAnsi;
  421. GODOT_TO_ACP_STACKALLOC(pName, pNameAnsi);
  422. if(pNameAnsi==NULL && pName != NULL)
  423. {
  424. return(FALSE);
  425. }
  426. return(AddPrinterA(pNameAnsi, Level, pPrinter));
  427. }
  428. End=
  429. [EFunc]
  430. TemplateName=AddPrinterDriverW
  431. Begin=
  432. BOOL __stdcall
  433. GodotAddPrinterDriverW(LPWSTR pName, DWORD Level, LPBYTE pDriverInfo)
  434. {
  435. LPSTR pNameAnsi;
  436. GODOT_TO_ACP_STACKALLOC(pName, pNameAnsi);
  437. if(!pNameAnsi && pName)
  438. return(FALSE);
  439. return(AddPrinterDriverA(pNameAnsi, Level, pDriverInfo));
  440. }
  441. End=
  442. [EFunc]
  443. TemplateName=AddPrintProcessorW
  444. Begin=
  445. BOOL __stdcall
  446. GodotAddPrintProcessorW(LPWSTR pName, LPWSTR pEnvironment, LPWSTR pPathName, LPWSTR pPrintProcessorName)
  447. {
  448. BOOL RetVal = FALSE;
  449. LPSTR pNameAnsi = NULL;
  450. LPSTR pEnvironmentAnsi = NULL;
  451. LPSTR pPathNameAnsi = NULL;
  452. LPSTR pPrintProcessorNameAnsi = NULL;
  453. ALLOCRETURN arName = GodotToAcpOnHeap(pName, &pNameAnsi);
  454. ALLOCRETURN arEnvironmentName = GodotToAcpOnHeap(pEnvironment, &pEnvironmentAnsi);
  455. ALLOCRETURN arPathName = GodotToAcpOnHeap(pPathName, &pPathNameAnsi);
  456. ALLOCRETURN arProcessorName = GodotToAcpOnHeap(pPrintProcessorName, &pPrintProcessorNameAnsi);
  457. if(arName != arFailed &&
  458. arEnvironmentName != arFailed &&
  459. arPathName != arFailed &&
  460. arProcessorName != arFailed)
  461. RetVal = AddPrintProcessorA(pNameAnsi, pEnvironmentAnsi, pPathNameAnsi, pPrintProcessorNameAnsi);
  462. if(arName==arAlloc)
  463. GodotHeapFree(pNameAnsi);
  464. if(arEnvironmentName==arAlloc)
  465. GodotHeapFree(pEnvironmentAnsi);
  466. if(arPathName==arAlloc)
  467. GodotHeapFree(pPathNameAnsi);
  468. if(arProcessorName==arAlloc)
  469. GodotHeapFree(pPrintProcessorNameAnsi);
  470. if(arName == arFailed ||
  471. arEnvironmentName == arFailed ||
  472. arPathName == arFailed ||
  473. arProcessorName == arFailed)
  474. SetLastError(ERROR_OUTOFMEMORY);
  475. return(RetVal);
  476. }
  477. End=
  478. [EFunc]
  479. TemplateName=AddPrintProviderW
  480. Begin=
  481. BOOL __stdcall
  482. GodotAddPrintProvidorW(LPWSTR pName, DWORD level, LPBYTE pProvidorInfo)
  483. {
  484. LPSTR pNameAnsi;
  485. PROVIDOR_INFO_1A pia;
  486. GODOT_TO_ACP_STACKALLOC(pName, pNameAnsi);
  487. GODOT_TO_ACP_STACKALLOC(((PROVIDOR_INFO_1)pProviderInfo)->pName, pia.pName);
  488. GODOT_TO_ACP_STACKALLOC(((PROVIDOR_INFO_1)pProviderInfo)->pEnvironment, pia.pEnvironment);
  489. GODOT_TO_ACP_STACKALLOC(((PROVIDOR_INFO_1)pProviderInfo)->pDLLName, pia.pDLLName);
  490. if((!pNameAnsi && pName) ||
  491. (!(pia.pName) && ((PROVIDOR_INFO_1)pProviderInfo)->pName) ||
  492. (!(pia.pEnvironment) && ((PROVIDOR_INFO_1)pProviderInfo)->pEnvironment) ||
  493. (!(pia.pDLLName) && ((PROVIDOR_INFO_1)pProviderInfo)->pDLLName))
  494. return(FALSE);
  495. return(AddPrintProvidorA(pNameAnsi, level, (LPBYTE)&pia));
  496. }
  497. End=
  498. [EFunc]
  499. TemplateName=AdvancedDocumentPropertiesW
  500. Begin=
  501. LONG __stdcall
  502. GodotAdvancedDocumentPropertiesW(HWND hWnd, HANDLE hPrinter, LPWSTR pDeviceName,
  503. PDEVMODEW pDevModeOutput, PDEVMODEW pDevModeInput)
  504. {
  505. LONG RetVal;
  506. LPSTR pDeviceNameAnsi;
  507. LPDEVMODEA lpdmaOutput;
  508. LPDEVMODEA lpdmaInput;
  509. size_t cbInput, cbOutput;
  510. if(pDevModeOutput==NULL || pDevModeInput==NULL)
  511. {
  512. SetLastError(ERROR_INVALID_PARAMETER);
  513. return(0);
  514. }
  515. cbInput = sizeof(DEVMODEA) + (pDevModeInput ? pDevModeInput->dmDriverExtra : 0);
  516. lpdmaInput = GodotHeapAlloc(cbInput);
  517. if(lpdmaInput==NULL)
  518. {
  519. SetLastError(ERROR_OUTOFMEMORY);
  520. return(0);
  521. }
  522. ZeroMemory(lpdmaInput, cbInput);
  523. DevModeAfromW(lpdmaInput, pDevModeInput);
  524. cbOutput = sizeof(DEVMODEA) + (pDevModeOutput ? pDevModeOutput->dmDriverExtra : 0);
  525. _STACKALLOC(cbOutput, lpdmaOutput);
  526. if(lpdmaOutput==NULL)
  527. {
  528. GodotHeapFree(lpdmaInput);
  529. return(0);
  530. }
  531. ZeroMemory(lpdmaOutput, cbOutput);
  532. GODOT_TO_ACP_STACKALLOC(pDeviceName, pDeviceNameAnsi);
  533. if(pDeviceNameAnsi==NULL && pDeviceName != NULL)
  534. {
  535. GodotHeapFree(lpdmaInput);
  536. return(0);
  537. }
  538. RetVal=AdvancedDocumentPropertiesA(hWnd, hPrinter, pDeviceNameAnsi, lpdmaOutput, lpdmaInput);
  539. if(RetVal)
  540. DevModeWfromA(pDevModeOutput, lpdmaOutput);
  541. GodotHeapFree(lpdmaInput);
  542. return RetVal;
  543. }
  544. End=
  545. [EFunc]
  546. TemplateName=AppendMenuW
  547. Begin=
  548. BOOL __stdcall GodotAppendMenuW(HMENU hMenu, UINT uFlags, UINT_PTR uIDNewItem, LPCWSTR lpNewItem)
  549. {
  550. // To detect the string case, we basically need to detect the
  551. // lack of the ownerdraw/bitmap case (since MF_STRING is
  552. // actually 0).
  553. if(!(uFlags & MF_BITMAP || uFlags & MF_OWNERDRAW))
  554. {
  555. LPSTR lpNewItemAnsi;
  556. GODOT_TO_ACP_STACKALLOC(lpNewItem, lpNewItemAnsi);
  557. return(AppendMenuA(hMenu, uFlags, uIDNewItem, lpNewItemAnsi));
  558. }
  559. return(AppendMenuA(hMenu, uFlags, uIDNewItem, (LPCSTR)lpNewItem));
  560. }
  561. End=
  562. [EFunc]
  563. TemplateName=auxGetDevCapsW
  564. Begin=
  565. MMRESULT __stdcall GodotauxGetDevCapsW(UINT_PTR uDeviceID, LPAUXCAPSW pac, UINT cbac)
  566. {
  567. // UNSUPPORTED FUNCTION: Documented as a failure stub
  568. if(cbac < sizeof(AUXCAPSW))
  569. {
  570. return(MMSYSERR_INVALPARAM);
  571. }
  572. else
  573. {
  574. AUXCAPSA acA;
  575. MMRESULT RetVal;
  576. ZeroMemory(&acA, sizeof(AUXCAPSA));
  577. RetVal = auxGetDevCapsA(uDeviceID, &acA, sizeof(AUXCAPSA));
  578. if(RetVal == MMSYSERR_NOERROR)
  579. {
  580. pac->wMid = acA.wMid;
  581. pac->wPid = acA.wPid;
  582. pac->vDriverVersion = acA.vDriverVersion;
  583. pac->wTechnology = acA.wTechnology;
  584. pac->wReserved1 = acA.wReserved1;
  585. pac->dwSupport = acA.dwSupport;
  586. MultiByteToWideChar(g_acp, 0, acA.szPname, MAXPNAMELEN, pac->szPname, MAXPNAMELEN);
  587. }
  588. return(RetVal);
  589. }
  590. }
  591. End=
  592. [EFunc]
  593. TemplateName=BeginUpdateResourceW
  594. Begin=
  595. HANDLE __stdcall GodotBeginUpdateResourceW(LPCWSTR pFileName, BOOL bDeleteExistingResources)
  596. {
  597. // UNSUPPORTED FUNCTION: Documented as a failure stub
  598. return(BeginUpdateResourceInternalW(pFileName, bDeleteExistingResources));
  599. }
  600. End=
  601. [EFunc]
  602. TemplateName=BroadcastSystemMessageW
  603. Begin=
  604. long __stdcall
  605. GodotBroadcastSystemMessageW(DWORD dwFlags, LPDWORD lpdwRcp, UINT uiMessage, WPARAM wParam, LPARAM lParam)
  606. {
  607. // Note that we overloaded a few params here rather than add even
  608. // more params to GodotTransmitMessage. Slightly hacky but it keeps
  609. // things central
  610. return(GodotTransmitMessage(mtBroadcastSystemMessage, 0, uiMessage, wParam,
  611. lParam, 0, 0, 0, (UINT)dwFlags, 0, lpdwRcp));
  612. }
  613. End=
  614. [EFunc]
  615. TemplateName=CallWindowProcA
  616. Begin=
  617. LRESULT __stdcall
  618. GodotCallWindowProcA(WNDPROC lpPrevWndFunc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  619. {
  620. return(GodotTransmitMessage(mtCallWindowProcA, hWnd, Msg, wParam, lParam,
  621. lpPrevWndFunc, 0, 0, 0, 0, 0));
  622. }
  623. End=
  624. [EFunc]
  625. TemplateName=CallWindowProcW
  626. Begin=
  627. LRESULT __stdcall
  628. GodotCallWindowProcW(WNDPROC lpPrevWndFunc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  629. {
  630. return(GodotTransmitMessage(mtCallWindowProc, hWnd, Msg, wParam, lParam,
  631. lpPrevWndFunc, 0, 0, 0, 0, 0));
  632. }
  633. End=
  634. [EFunc]
  635. TemplateName=capCreateCaptureWindowW
  636. Begin=
  637. HWND __stdcall
  638. GodotcapCreateCaptureWindowW( LPCWSTR lpszWindowName,
  639. DWORD dwStyle,
  640. int x,
  641. int y,
  642. int nWidth,
  643. int nHeight,
  644. HWND hwndParent,
  645. int nID
  646. )
  647. {
  648. HWND RetVal;
  649. LPSTR lpszWindowNameAnsi;
  650. LPGODOTTLSINFO lpgti = GetThreadInfoSafe(TRUE);
  651. GODOT_TO_ACP_STACKALLOC(lpszWindowName, lpszWindowNameAnsi);
  652. if(!lpgti ||
  653. (!lpszWindowNameAnsi && lpszWindowName))
  654. return(0);
  655. INIT_WINDOW_SNIFF(lpgti->hHook);
  656. RetVal=capCreateCaptureWindowA(lpszWindowNameAnsi, dwStyle, x, y, nWidth, nHeight, hwndParent, nID);
  657. TERM_WINDOW_SNIFF(lpgti->hHook);
  658. return RetVal;
  659. }
  660. End=
  661. [EFunc]
  662. TemplateName=capGetDriverDescriptionW
  663. Begin=
  664. BOOL __stdcall
  665. GodotcapGetDriverDescriptionW(UINT wDriverIndex, LPWSTR lpszName, int cbName, LPWSTR lpszVer, int cbVer)
  666. {
  667. BOOL RetVal;
  668. LPSTR lpszNameAnsi;
  669. LPSTR lpszVerAnsi;
  670. _STACKALLOC((cbName*g_mcs)+1, lpszNameAnsi);
  671. _STACKALLOC((cbVer*g_mcs)+1, lpszVerAnsi);
  672. if((lpszNameAnsi==NULL) || (lpszVerAnsi==NULL))
  673. return(FALSE);
  674. ZeroMemory(lpszNameAnsi, (cbName*g_mcs)+1);
  675. ZeroMemory(lpszVerAnsi, (cbVer*g_mcs)+1);
  676. RetVal=capGetDriverDescriptionA(wDriverIndex, lpszNameAnsi, cbName, lpszVerAnsi, cbVer);
  677. if(RetVal)
  678. {
  679. MultiByteToWideChar(g_acp, 0, lpszNameAnsi, -1, lpszName, cbName);
  680. MultiByteToWideChar(g_acp, 0, lpszVerAnsi, -1, lpszVer, cbVer);
  681. }
  682. return(RetVal);
  683. }
  684. End=
  685. [EFunc]
  686. TemplateName=CharToOemW
  687. Begin=
  688. BOOL __stdcall
  689. GodotCharToOemW(LPCWSTR lpszSrc, LPSTR lpszDst)
  690. {
  691. size_t cchSrc;
  692. // MSDN claims this function never returns FALSE. It lies (in the
  693. // case where the buffers are identical, for example).
  694. if ((void *)lpszSrc == (void *)lpszDst)
  695. {
  696. SetLastError(ERROR_INVALID_ADDRESS);
  697. return(FALSE);
  698. }
  699. // Why thunk? This function is just a WCHAR->CP_OEM converter, anyway!
  700. // We should never be longer than the unicode string * g_mcs
  701. cchSrc = gwcslen(lpszSrc);
  702. // (Copied the default char choice from oemxlate.c in the Windows depot).
  703. WideCharToMultiByte(g_oemcp, 0, lpszSrc, cchSrc, lpszDst, cchSrc*g_mcs, "_", NULL);
  704. return(TRUE);
  705. }
  706. End=
  707. [EFunc]
  708. TemplateName=CharToOemBuffW
  709. Begin=
  710. BOOL __stdcall
  711. GodotCharToOemBuffW(LPCWSTR lpszSrc, LPSTR lpszDst, DWORD cchDstLength)
  712. {
  713. LPSTR pTemp;
  714. // MSDN claims this function never returns FALSE. It lies (in the
  715. // case where the buffers are identical, for example).
  716. if ((void *)lpszSrc == (void *)lpszDst)
  717. {
  718. SetLastError(ERROR_INVALID_ADDRESS);
  719. return(FALSE);
  720. }
  721. // Validate the input and output pointers (taken from the actual API)
  722. if(IsBadReadPtr(pTemp = (LPSTR)lpszSrc, cchDstLength) ||
  723. IsBadWritePtr(pTemp = (LPSTR)lpszDst, cchDstLength))
  724. {
  725. SetLastError(ERROR_INVALID_PARAMETER);
  726. return(FALSE);
  727. }
  728. // Why thunk? This function is just a WCHAR->CP_OEM converter, anyway!
  729. // (Copied the default char choice from oemxlate.c in the Windows depot).
  730. WideCharToMultiByte(g_oemcp, 0, lpszSrc, cchDstLength, lpszDst, cchDstLength*g_mcs, "_", NULL);
  731. return(TRUE);
  732. }
  733. End=
  734. [EFunc]
  735. TemplateName=ChangeDisplaySettingsW
  736. Begin=
  737. LONG __stdcall
  738. GodotChangeDisplaySettingsW(LPDEVMODEW lpDevMode, DWORD dwFlags)
  739. {
  740. LPDEVMODEA lpdma;
  741. _STACKALLOC(sizeof(DEVMODEA) + lpDevMode->dmDriverExtra, lpdma);
  742. if(lpdma==NULL)
  743. {
  744. return(DISP_CHANGE_FAILED);
  745. }
  746. ZeroMemory(lpdma, sizeof(DEVMODEA) + lpDevMode->dmDriverExtra);
  747. if(lpDevMode)
  748. DevModeAfromW(lpdma, lpDevMode);
  749. return(ChangeDisplaySettingsA(lpdma, dwFlags));
  750. }
  751. End=
  752. [EFunc]
  753. TemplateName=ChangeDisplaySettingsExW
  754. Begin=
  755. LONG __stdcall
  756. GodotChangeDisplaySettingsExW( LPCWSTR lpszDeviceName,
  757. LPDEVMODEW lpDevMode,
  758. HWND hwnd,
  759. DWORD dwflags,
  760. LPVOID lParam
  761. )
  762. {
  763. // Begin locals
  764. LONG RetVal = DISP_CHANGE_FAILED;
  765. if (s_pfnChangeDisplaySettingsExA == NULL)
  766. {
  767. // Must allocate stuff for this API call
  768. s_pfnChangeDisplaySettingsExA = (PFNcdsea)GetUserProc("ChangeDisplaySettingsExA");
  769. }
  770. if (s_pfnChangeDisplaySettingsExA)
  771. {
  772. LPSTR lpszDeviceNameAnsi;
  773. LPDEVMODEA lpdma;
  774. _STACKALLOC(sizeof(DEVMODEA) + (lpDevMode ? lpDevMode->dmDriverExtra : 0), lpdma);
  775. if(lpdma==NULL)
  776. {
  777. return(DISP_CHANGE_FAILED);
  778. }
  779. ZeroMemory(lpdma, sizeof(DEVMODEA) + (lpDevMode ? lpDevMode->dmDriverExtra : 0));
  780. if(lpDevMode)
  781. DevModeAfromW(lpdma, lpDevMode);
  782. GODOT_TO_ACP_STACKALLOC(lpszDeviceName, lpszDeviceNameAnsi);
  783. RetVal=(s_pfnChangeDisplaySettingsExA(lpszDeviceNameAnsi, lpdma, hwnd, dwflags, lParam));
  784. }
  785. else
  786. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  787. // Finished
  788. return RetVal;
  789. }
  790. End=
  791. [EFunc]
  792. TemplateName=CharLowerW
  793. Begin=
  794. LPWSTR __stdcall
  795. GodotCharLowerW(LPWSTR lpsz)
  796. {
  797. if(lpsz)
  798. {
  799. if (FSTRING_VALID(lpsz))
  800. {
  801. CaseHelper(lpsz, (DWORD)-1, FALSE);
  802. }
  803. else
  804. {
  805. CaseHelper((LPWSTR)&lpsz, 1, FALSE);
  806. }
  807. }
  808. return lpsz;
  809. }
  810. End=
  811. [EFunc]
  812. TemplateName=CharLowerBuffW
  813. Begin=
  814. DWORD __stdcall
  815. GodotCharLowerBuffW(LPWSTR lpsz, DWORD cchLength)
  816. {
  817. if (!lpsz || !cchLength)
  818. return 0;
  819. CaseHelper(lpsz, cchLength, FALSE);
  820. return cchLength;
  821. }
  822. End=
  823. [EFunc]
  824. TemplateName=CharNextW
  825. Begin=
  826. LPWSTR __stdcall
  827. GodotCharNextW(LPCWSTR lpsz)
  828. {
  829. LPWSTR RetVal = (LPWSTR)lpsz;
  830. if (lpsz && (L'\0' != *lpsz))
  831. RetVal++; // this is what _wcsinc does
  832. return RetVal;
  833. }
  834. End=
  835. [EFunc]
  836. TemplateName=CharPrevW
  837. Begin=
  838. LPWSTR __stdcall
  839. GodotCharPrevW(LPCWSTR lpszStart, LPCWSTR lpszCurrent)
  840. {
  841. LPWSTR RetVal = (LPWSTR)lpszCurrent;
  842. if (lpszStart && lpszCurrent && (lpszCurrent > lpszStart))
  843. RetVal--; // this is what _wcsdec does
  844. else
  845. RetVal = (LPWSTR)lpszStart;
  846. return RetVal;
  847. }
  848. End=
  849. [EFunc]
  850. TemplateName=CharUpperW
  851. Begin=
  852. LPWSTR __stdcall
  853. GodotCharUpperW(LPWSTR lpsz)
  854. {
  855. if(lpsz)
  856. {
  857. if (FSTRING_VALID(lpsz))
  858. CaseHelper(lpsz, (DWORD)-1, TRUE);
  859. else
  860. CaseHelper((LPWSTR)&lpsz, 1, TRUE);
  861. }
  862. return lpsz;
  863. }
  864. End=
  865. [EFunc]
  866. TemplateName=CharUpperBuffW
  867. Begin=
  868. DWORD __stdcall
  869. GodotCharUpperBuffW(LPWSTR lpsz, DWORD cchLength)
  870. {
  871. if (!lpsz || !cchLength)
  872. return 0;
  873. CaseHelper(lpsz, cchLength, TRUE);
  874. return cchLength;
  875. }
  876. End=
  877. [EFunc]
  878. TemplateName=ChooseColorW
  879. Begin=
  880. BOOL __stdcall
  881. GodotChooseColorW(LPCHOOSECOLORW lpcc)
  882. {
  883. // Begin locals
  884. BOOL RetVal;
  885. CHOOSECOLORA ccAnsi;
  886. LPGODOTTLSINFO lpgti;
  887. // If we cannot get out TLS info, then we cannot proceed
  888. if(!(lpgti = GetThreadInfoSafe(TRUE)))
  889. {
  890. SetLastError(ERROR_OUTOFMEMORY);
  891. return(0);
  892. }
  893. ZeroMemory(&ccAnsi, sizeof(CHOOSECOLORA));
  894. // Do the hook
  895. if((lpgti->pfnChooseColor) && (lpcc->Flags & CC_ENABLEHOOK) && (lpcc->lpfnHook))
  896. {
  897. SetLastError(ERROR_INVALID_FILTER_PROC);
  898. return(0);
  899. }
  900. if ((lpcc->Flags & CC_ENABLEHOOK) && (lpcc->lpfnHook))
  901. lpgti->pfnChooseColor = lpcc->lpfnHook;
  902. ccAnsi.lpfnHook = &CCHookProc;
  903. ccAnsi.lStructSize = sizeof(CHOOSECOLORA);
  904. ccAnsi.hwndOwner = lpcc->hwndOwner;
  905. if((lpcc->Flags & CC_ENABLETEMPLATEHANDLE) || (lpcc->Flags & CC_ENABLETEMPLATE))
  906. ccAnsi.hInstance = lpcc->hInstance;
  907. ccAnsi.rgbResult = lpcc->rgbResult;
  908. ccAnsi.lpCustColors = lpcc->lpCustColors; // pointer to an array of 16 COLORREFs
  909. ccAnsi.Flags = lpcc->Flags;
  910. ccAnsi.lCustData = lpcc->lCustData;
  911. if(lpcc->Flags & CC_ENABLETEMPLATE)
  912. {
  913. GODOT_TO_ACP_STACKALLOC(lpcc->lpTemplateName, ccAnsi.lpTemplateName);
  914. }
  915. INIT_WINDOW_SNIFF(lpgti->hHook);
  916. RetVal=ChooseColorA(&ccAnsi);
  917. TERM_WINDOW_SNIFF(lpgti->hHook);
  918. if ((lpcc->Flags & CC_ENABLEHOOK) && (lpcc->lpfnHook))
  919. lpgti->pfnChooseColor = NULL;
  920. // Begin postcall
  921. if(RetVal)
  922. {
  923. lpcc->rgbResult = ccAnsi.rgbResult;
  924. lpcc->lpCustColors = ccAnsi.lpCustColors; // pointer to an array of 16 COLORREFs
  925. lpcc->Flags = ccAnsi.Flags;
  926. lpcc->lCustData = ccAnsi.lCustData;
  927. }
  928. // Finished
  929. return RetVal;
  930. }
  931. End=
  932. [EFunc]
  933. TemplateName=ChooseFontW
  934. Begin=
  935. BOOL __stdcall
  936. GodotChooseFontW(LPCHOOSEFONTW lpcf)
  937. {
  938. // Begin locals
  939. BOOL RetVal;
  940. CHOOSEFONTA cfa;
  941. LPGODOTTLSINFO lpgti;
  942. // If we cannot get out TLS info, then we cannot proceed
  943. if(!(lpgti = GetThreadInfoSafe(TRUE)))
  944. {
  945. SetLastError(ERROR_OUTOFMEMORY);
  946. return(0);
  947. }
  948. ZeroMemory(&cfa, sizeof(CHOOSEFONTA));
  949. // Do the hook
  950. if((lpgti->pfnChooseFont) && (lpcf->Flags & CF_ENABLEHOOK) && (lpcf->lpfnHook))
  951. {
  952. SetLastError(ERROR_INVALID_FILTER_PROC);
  953. return(0);
  954. }
  955. if ((lpcf->Flags & CF_ENABLEHOOK) && (lpcf->lpfnHook))
  956. lpgti->pfnChooseFont = lpcf->lpfnHook;
  957. cfa.lpfnHook = &CFHookProc;
  958. cfa.lStructSize = sizeof(CHOOSEFONTA);
  959. cfa.hwndOwner = lpcf->hwndOwner;
  960. if((lpcf->Flags & CF_PRINTERFONTS) || (lpcf->Flags & CF_BOTH))
  961. cfa.hDC = lpcf->hDC;
  962. _STACKALLOC(sizeof(LOGFONTA), cfa.lpLogFont);
  963. ZeroMemory(cfa.lpLogFont, sizeof(LOGFONTA));
  964. LogFontAfromW(cfa.lpLogFont, lpcf->lpLogFont);
  965. cfa.iPointSize = lpcf->iPointSize;
  966. cfa.Flags = lpcf->Flags;
  967. cfa.rgbColors = lpcf->rgbColors;
  968. cfa.lCustData = lpcf->lCustData;
  969. if(lpcf->Flags & CF_ENABLETEMPLATE)
  970. {
  971. GODOT_TO_ACP_STACKALLOC(lpcf->lpTemplateName, cfa.lpTemplateName);
  972. }
  973. //if((lpcf->Flags & CF_ENABLETEMPLATEHANDLE) || (lpcf->Flags & CF_ENABLETEMPLATE))
  974. cfa.hInstance = lpcf->hInstance;
  975. GODOT_TO_ACP_STACKALLOC(lpcf->lpszStyle, cfa.lpszStyle);
  976. cfa.nFontType = lpcf->nFontType;
  977. cfa.nSizeMin = lpcf->nSizeMin;
  978. cfa.nSizeMax = lpcf->nSizeMax;
  979. INIT_WINDOW_SNIFF(lpgti->hHook);
  980. RetVal=ChooseFontA(&cfa);
  981. TERM_WINDOW_SNIFF(lpgti->hHook);
  982. if ((lpcf->Flags & CF_ENABLEHOOK) && (lpcf->lpfnHook))
  983. lpgti->pfnChooseFont = NULL;
  984. // Begin postcall
  985. if(RetVal)
  986. {
  987. size_t cbStyle;
  988. lpcf->hDC = cfa.hDC;
  989. LogFontWfromA(lpcf->lpLogFont, cfa.lpLogFont);
  990. lpcf->iPointSize = cfa.iPointSize;
  991. lpcf->Flags = cfa.Flags;
  992. lpcf->rgbColors = cfa.rgbColors;
  993. lpcf->lCustData = cfa.lCustData;
  994. cbStyle = (lpcf->lpszStyle==NULL ? 0 : lstrlenA( cfa.lpszStyle));
  995. if(FSTRING_VALID(cfa.lpszStyle) && FSTRING_VALID(lpcf->lpszStyle) && (cbStyle > 0))
  996. MultiByteToWideChar(g_acp, 0, cfa.lpszStyle, -1, lpcf->lpszStyle, cbStyle);
  997. lpcf->nFontType = cfa.nFontType;
  998. lpcf->nSizeMin = cfa.nSizeMin;
  999. lpcf->nSizeMax = cfa.nSizeMax;
  1000. }
  1001. // Finished
  1002. return RetVal;
  1003. }
  1004. End=
  1005. [EFunc]
  1006. TemplateName=CompareStringW
  1007. Begin=
  1008. int __stdcall
  1009. GodotCompareStringW( LCID Locale,
  1010. DWORD dwCmpFlags,
  1011. LPCWSTR lpString1,
  1012. int cchCount1,
  1013. LPCWSTR lpString2,
  1014. int cchCount2
  1015. )
  1016. {
  1017. // Begin locals
  1018. int RetVal;
  1019. LPSTR lpString1A, lpString2A;
  1020. size_t cchString1, cchString2;
  1021. UINT cpg;
  1022. UINT mcs;
  1023. cpg = CpgFromLocale(Locale);
  1024. mcs = CbPerChOfCpg(cpg);
  1025. // Begin precall
  1026. if (FSTRING_VALID(lpString1))
  1027. {
  1028. if(cchCount1==-1)
  1029. cchString1 = gwcslen(lpString1) + 1;
  1030. else
  1031. cchString1 = cchCount1 + 1;
  1032. _STACKALLOC(cchString1*mcs, lpString1A);
  1033. if(!lpString1A)
  1034. {
  1035. return(FALSE);
  1036. }
  1037. WideCharToMultiByte(cpg, 0, lpString1, cchString1, lpString1A, cchString1*mcs, NULL, NULL);
  1038. }
  1039. else
  1040. lpString1A = (LPSTR)lpString1;
  1041. if (FSTRING_VALID(lpString2))
  1042. {
  1043. if(cchCount2==-1)
  1044. cchString2 = gwcslen(lpString2) + 1;
  1045. else
  1046. cchString2 = cchCount2 + 1;
  1047. _STACKALLOC(cchString2*mcs, lpString2A);
  1048. if(!lpString2A)
  1049. {
  1050. return(FALSE);
  1051. }
  1052. WideCharToMultiByte(cpg, 0, lpString2, cchString2, lpString2A, cchString2*mcs, NULL, NULL);
  1053. }
  1054. else
  1055. lpString2A = (LPSTR)lpString2;
  1056. RetVal=CompareStringA(Locale, dwCmpFlags, lpString1A, cchCount1, lpString2A, cchCount2);
  1057. // Finished
  1058. return RetVal;
  1059. }
  1060. End=
  1061. [EFunc]
  1062. TemplateName=ConfigurePortW
  1063. Begin=
  1064. BOOL __stdcall GodotConfigurePortW(LPWSTR pName, HWND hWnd, LPWSTR pPortName)
  1065. {
  1066. BOOL RetVal = FALSE;
  1067. LPSTR pNameAnsi = NULL;
  1068. LPSTR pPortNameAnsi = NULL;
  1069. ALLOCRETURN arName = GodotToAcpOnHeap(pName, &pNameAnsi);
  1070. ALLOCRETURN arPortName = GodotToAcpOnHeap(pPortName, &pPortNameAnsi);
  1071. if(arName != arFailed && arPortName != arFailed)
  1072. RetVal = ConfigurePortA(pNameAnsi, hWnd, pPortNameAnsi);
  1073. if(arName==arAlloc)
  1074. GodotHeapFree(pNameAnsi);
  1075. if(arPortName==arAlloc)
  1076. GodotHeapFree(pPortNameAnsi);
  1077. if(arName == arFailed || arPortName == arFailed)
  1078. SetLastError(ERROR_OUTOFMEMORY);
  1079. return(RetVal);
  1080. }
  1081. End=
  1082. [EFunc]
  1083. TemplateName=CopyFileW
  1084. Begin=
  1085. BOOL __stdcall
  1086. GodotCopyFileW(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName, BOOL bFailIfExists)
  1087. {
  1088. LPSTR lpExistingFileNameA, lpNewFileNameA;
  1089. UINT cpg = FILES_CPG;
  1090. // Begin precall
  1091. GODOT_TO_CPG_STACKALLOC(lpExistingFileName, lpExistingFileNameA, cpg, g_mcs);
  1092. GODOT_TO_CPG_STACKALLOC(lpNewFileName, lpNewFileNameA, cpg, g_mcs);
  1093. return(CopyFileA(lpExistingFileNameA, lpNewFileNameA, bFailIfExists));
  1094. }
  1095. End=
  1096. [EFunc]
  1097. TemplateName=CopyFileExW
  1098. Begin=
  1099. BOOL __stdcall
  1100. GodotCopyFileExW( LPCWSTR lpExisting,
  1101. LPCWSTR lpNew,
  1102. LPPROGRESS_ROUTINE lpProgress,
  1103. LPVOID lpData,
  1104. LPBOOL pbCancel,
  1105. DWORD dwCopyFlags
  1106. )
  1107. {
  1108. // Begin locals
  1109. LPSTR lpEfnA, lpNfnA;
  1110. UINT cpg = FILES_CPG;
  1111. if (s_pfnCopyFileExA == NULL)
  1112. {
  1113. // Must allocate stuff for this API call
  1114. s_pfnCopyFileExA = (PFNcfea)GetKernelProc("CopyFileExA");
  1115. }
  1116. if (s_pfnCopyFileExA)
  1117. {
  1118. GODOT_TO_CPG_STACKALLOC(lpExisting, lpEfnA, cpg, g_mcs);
  1119. GODOT_TO_CPG_STACKALLOC(lpNew, lpNfnA, cpg, g_mcs);
  1120. return((s_pfnCopyFileExA(lpEfnA, lpNfnA, lpProgress, lpData, pbCancel, dwCopyFlags)));
  1121. }
  1122. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1123. return FALSE;
  1124. }
  1125. End=
  1126. [EFunc]
  1127. TemplateName=CreateColorSpaceW
  1128. Begin=
  1129. HCOLORSPACE __stdcall
  1130. GodotCreateColorSpaceW(LPLOGCOLORSPACEW plcs)
  1131. {
  1132. LOGCOLORSPACEA lcsa;
  1133. // Begin precall
  1134. ZeroMemory(&lcsa, sizeof(LOGCOLORSPACEA));
  1135. memcpy(&lcsa, plcs, 6*sizeof(DWORD)+sizeof(LCSCSTYPE)+sizeof(LCSGAMUTMATCH)+sizeof(CIEXYZTRIPLE));
  1136. lcsa.lcsSize = sizeof(LOGCOLORSPACEA);
  1137. WideCharToMultiByte(g_acp, 0,
  1138. plcs->lcsFilename, MAX_PATH,
  1139. lcsa.lcsFilename, MAX_PATH,
  1140. NULL, NULL);
  1141. return(CreateColorSpaceA(&lcsa));
  1142. }
  1143. End=
  1144. [EFunc]
  1145. TemplateName=CreateDCW
  1146. Begin=
  1147. HDC __stdcall
  1148. GodotCreateDCW(LPCWSTR lpszDriver, LPCWSTR lpszDevice, LPCWSTR lpszOutput, DEVMODEW * lpInitData)
  1149. {
  1150. LPSTR lpszDriverAnsi, lpszDeviceAnsi, lpszOutputAnsi;
  1151. LPDEVMODEA lpdma;
  1152. // Begin precall
  1153. GODOT_TO_ACP_STACKALLOC(lpszDriver, lpszDriverAnsi);
  1154. GODOT_TO_ACP_STACKALLOC(lpszDevice, lpszDeviceAnsi);
  1155. GODOT_TO_ACP_STACKALLOC(lpszOutput, lpszOutputAnsi);
  1156. if((!lpszDriverAnsi && lpszDriver) ||
  1157. (!lpszDeviceAnsi && lpszDevice) ||
  1158. (!lpszOutputAnsi && lpszOutput))
  1159. {
  1160. return(0);
  1161. }
  1162. if (lpInitData)
  1163. {
  1164. _STACKALLOC(sizeof(DEVMODEA) + lpInitData->dmDriverExtra, lpdma);
  1165. if(lpdma==NULL)
  1166. {
  1167. return(0);
  1168. }
  1169. ZeroMemory(lpdma, sizeof(DEVMODEA) + lpInitData->dmDriverExtra);
  1170. DevModeAfromW(lpdma, lpInitData);
  1171. return(CreateDCA(lpszDriverAnsi, lpszDeviceAnsi, lpszOutputAnsi, lpdma));
  1172. }
  1173. else
  1174. return(CreateDCA(lpszDriverAnsi, lpszDeviceAnsi, lpszOutputAnsi, NULL));
  1175. }
  1176. End=
  1177. [EFunc]
  1178. TemplateName=CreateDialogIndirectParamW
  1179. Begin=
  1180. HWND __stdcall
  1181. GodotCreateDialogIndirectParamW( HINSTANCE hInst,
  1182. LPCDLGTEMPLATEW lpTemplate,
  1183. HWND hWnd,
  1184. DLGPROC lpfn,
  1185. LPARAM dwParam
  1186. )
  1187. {
  1188. LPGODOTTLSINFO lpgti = GetThreadInfoSafe(TRUE);
  1189. HWND RetVal;
  1190. if(!lpgti)
  1191. {
  1192. RetVal = 0;
  1193. }
  1194. else
  1195. {
  1196. lpgti->pfnDlgProc = lpfn;
  1197. INIT_WINDOW_SNIFF(lpgti->hHook);
  1198. RetVal = CreateDialogIndirectParamA(hInst, lpTemplate, hWnd, &DialogProc, dwParam);
  1199. TERM_WINDOW_SNIFF(lpgti->hHook);
  1200. }
  1201. return(RetVal);
  1202. }
  1203. End=
  1204. [EFunc]
  1205. TemplateName=CreateDialogParamW
  1206. Begin=
  1207. HWND __stdcall
  1208. GodotCreateDialogParamW(HINSTANCE hInst, LPCWSTR lpTemplate, HWND hWnd, DLGPROC lpfn, LPARAM dwParam)
  1209. {
  1210. LPGODOTTLSINFO lpgti = GetThreadInfoSafe(TRUE);
  1211. if(!lpgti)
  1212. {
  1213. return(0);
  1214. }
  1215. else
  1216. {
  1217. LPSTR lpTemplateAnsi;
  1218. HWND RetVal;
  1219. lpgti->pfnDlgProc = lpfn;
  1220. GODOT_TO_ACP_STACKALLOC(lpTemplate, lpTemplateAnsi);
  1221. if(!lpTemplateAnsi && lpTemplate)
  1222. return(0);
  1223. INIT_WINDOW_SNIFF(lpgti->hHook);
  1224. RetVal = CreateDialogParamA(hInst, lpTemplateAnsi, hWnd, &DialogProc, dwParam);
  1225. TERM_WINDOW_SNIFF(lpgti->hHook);
  1226. return(RetVal);
  1227. }
  1228. }
  1229. End=
  1230. [EFunc]
  1231. TemplateName=CreateDirectoryW
  1232. Begin=
  1233. BOOL __stdcall
  1234. GodotCreateDirectoryW(LPCWSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
  1235. {
  1236. // Begin locals
  1237. LPSTR lpPathNameAnsi;
  1238. // Begin precall
  1239. GODOT_TO_CPG_STACKALLOC(lpPathName, lpPathNameAnsi, FILES_CPG, g_mcs);
  1240. return(CreateDirectoryA(lpPathNameAnsi, lpSecurityAttributes));
  1241. }
  1242. End=
  1243. [EFunc]
  1244. TemplateName=CreateDirectoryExW
  1245. Begin=
  1246. BOOL __stdcall
  1247. GodotCreateDirectoryExW(LPCWSTR lpTemplate, LPCWSTR lpNew, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
  1248. {
  1249. // Begin locals
  1250. LPSTR lpTemplateAnsi, lpNewAnsi;
  1251. UINT cpg = FILES_CPG;
  1252. // Begin precall
  1253. GODOT_TO_CPG_STACKALLOC(lpTemplate, lpTemplateAnsi, cpg, g_mcs);
  1254. GODOT_TO_CPG_STACKALLOC(lpNew, lpNewAnsi, cpg, g_mcs);
  1255. return(CreateDirectoryExA(lpTemplateAnsi, lpNewAnsi, lpSecurityAttributes));
  1256. }
  1257. End=
  1258. [EFunc]
  1259. TemplateName=CreateFileW
  1260. Begin=
  1261. HANDLE __stdcall
  1262. GodotCreateFileW( LPCWSTR lpFileName,
  1263. DWORD dwDesiredAccess,
  1264. DWORD dwShareMode,
  1265. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  1266. DWORD dwCreationDisposition,
  1267. DWORD dwFlagsAndAttributes,
  1268. HANDLE hTemplateFile
  1269. )
  1270. {
  1271. LPSTR lpFileNameAnsi;
  1272. // Begin precall
  1273. GODOT_TO_CPG_STACKALLOC(lpFileName, lpFileNameAnsi, FILES_CPG, g_mcs);
  1274. return(CreateFileA(lpFileNameAnsi,
  1275. dwDesiredAccess,
  1276. dwShareMode,
  1277. lpSecurityAttributes,
  1278. dwCreationDisposition,
  1279. dwFlagsAndAttributes,
  1280. hTemplateFile
  1281. ));
  1282. }
  1283. End=
  1284. [EFunc]
  1285. TemplateName=CreateFontIndirectW
  1286. Begin=
  1287. HFONT __stdcall
  1288. GodotCreateFontIndirectW(LOGFONTW * lplf
  1289. )
  1290. {
  1291. LOGFONTA lfa;
  1292. ZeroMemory(&lfa, sizeof(LOGFONTA));
  1293. LogFontAfromW(&lfa, lplf);
  1294. return(CreateFontIndirectA(&lfa));
  1295. }
  1296. End=
  1297. [EFunc]
  1298. TemplateName=CreateICW
  1299. Begin=
  1300. HDC __stdcall
  1301. GodotCreateICW( LPCWSTR lpszDriver,
  1302. LPCWSTR lpszDevice,
  1303. LPCWSTR lpszOutput,
  1304. DEVMODEW * lpdvmInit
  1305. )
  1306. {
  1307. LPSTR lpszDriverAnsi, lpszDeviceAnsi;
  1308. LPDEVMODEA lpdma;
  1309. // Begin precall
  1310. GODOT_TO_ACP_STACKALLOC(lpszDriver, lpszDriverAnsi);
  1311. GODOT_TO_ACP_STACKALLOC(lpszDevice, lpszDeviceAnsi);
  1312. if((!lpszDriverAnsi && lpszDriver) ||
  1313. (!lpszDeviceAnsi && lpszDevice))
  1314. {
  1315. return(0);
  1316. }
  1317. if(lpdvmInit)
  1318. {
  1319. _STACKALLOC(sizeof(DEVMODEA) + lpdvmInit->dmDriverExtra, lpdma);
  1320. if(lpdma==NULL)
  1321. {
  1322. return(0);
  1323. }
  1324. ZeroMemory(lpdma, sizeof(DEVMODEA) + lpdvmInit->dmDriverExtra);
  1325. DevModeAfromW(lpdma, lpdvmInit);
  1326. return(CreateICA(lpszDriverAnsi, lpszDeviceAnsi, NULL, lpdma));
  1327. }
  1328. else
  1329. return(CreateICA(lpszDriverAnsi, lpszDeviceAnsi, NULL, NULL));
  1330. }
  1331. End=
  1332. [EFunc]
  1333. TemplateName=CreateMDIWindowW
  1334. Begin=
  1335. HWND __stdcall
  1336. GodotCreateMDIWindowW( LPCWSTR lpClassName,
  1337. LPCWSTR lpWindowName,
  1338. DWORD dwStyle,
  1339. int X,
  1340. int Y,
  1341. int nWidth,
  1342. int nHeight,
  1343. HWND hWndParent,
  1344. HINSTANCE hInstance,
  1345. LPARAM lParam
  1346. )
  1347. {
  1348. HWND RetVal;
  1349. LPSTR lpClassNameAnsi, lpWindowNameAnsi;
  1350. LPGODOTTLSINFO lpgti = GetThreadInfoSafe(TRUE);
  1351. GODOT_TO_ACP_STACKALLOC(lpClassName, lpClassNameAnsi);
  1352. GODOT_TO_ACP_STACKALLOC(lpWindowName, lpWindowNameAnsi);
  1353. if(!lpgti ||
  1354. (lpClassName && !lpClassNameAnsi) ||
  1355. (lpWindowName && !lpWindowNameAnsi))
  1356. return(0);
  1357. INIT_WINDOW_SNIFF(lpgti->hHook);
  1358. RetVal=CreateMDIWindowA(lpClassNameAnsi, lpWindowNameAnsi, dwStyle, X, Y,
  1359. nWidth, nHeight, hWndParent, hInstance, lParam);
  1360. TERM_WINDOW_SNIFF(lpgti->hHook);
  1361. // Finished
  1362. return RetVal;
  1363. }
  1364. End=
  1365. [EFunc]
  1366. TemplateName=CreateProcessW
  1367. Begin=
  1368. BOOL __stdcall
  1369. GodotCreateProcessW( LPCWSTR lpApplicationName,
  1370. LPWSTR lpCommandLine,
  1371. LPSECURITY_ATTRIBUTES lpProcessAttributes,
  1372. LPSECURITY_ATTRIBUTES lpThreadAttributes,
  1373. BOOL bInheritHandles,
  1374. DWORD dwCreationFlags,
  1375. LPVOID lpEnvironment,
  1376. LPCWSTR lpCurrentDirectory,
  1377. LPSTARTUPINFOW lpsiw,
  1378. LPPROCESS_INFORMATION lpProcessInformation
  1379. )
  1380. {
  1381. LPSTR lpApplicationNameAnsi, lpCommandLineAnsi, lpCurrentDirectoryAnsi;
  1382. STARTUPINFOA sia;
  1383. // Begin precall
  1384. ZeroMemory(&sia, sizeof(STARTUPINFOA));
  1385. GODOT_TO_ACP_STACKALLOC(lpApplicationName, lpApplicationNameAnsi);
  1386. GODOT_TO_ACP_STACKALLOC(lpCommandLine, lpCommandLineAnsi);
  1387. GODOT_TO_ACP_STACKALLOC(lpCurrentDirectory, lpCurrentDirectoryAnsi);
  1388. sia.cb = sizeof(STARTUPINFOA);
  1389. GODOT_TO_ACP_STACKALLOC(lpsiw->lpReserved, sia.lpReserved);
  1390. GODOT_TO_ACP_STACKALLOC(lpsiw->lpDesktop, sia.lpDesktop);
  1391. GODOT_TO_ACP_STACKALLOC(lpsiw->lpTitle, sia.lpTitle);
  1392. sia.dwX = lpsiw->dwX;
  1393. sia.dwY = lpsiw->dwY;
  1394. sia.dwXSize = lpsiw->dwXSize;
  1395. sia.dwYSize = lpsiw->dwYSize;
  1396. sia.dwXCountChars = lpsiw->dwXCountChars;
  1397. sia.dwYCountChars = lpsiw->dwYCountChars;
  1398. sia.dwFillAttribute = lpsiw->dwFillAttribute;
  1399. sia.dwFlags = lpsiw->dwFlags;
  1400. sia.wShowWindow = lpsiw->wShowWindow;
  1401. sia.cbReserved2 = lpsiw->cbReserved2;
  1402. sia.lpReserved2 = lpsiw->lpReserved2;
  1403. sia.hStdInput = lpsiw->hStdInput;
  1404. sia.hStdOutput = lpsiw->hStdOutput;
  1405. sia.hStdError = lpsiw->hStdError;
  1406. return(CreateProcessA(lpApplicationNameAnsi,
  1407. lpCommandLineAnsi,
  1408. lpProcessAttributes,
  1409. lpThreadAttributes,
  1410. bInheritHandles,
  1411. dwCreationFlags,
  1412. lpEnvironment,
  1413. lpCurrentDirectoryAnsi,
  1414. &sia,
  1415. lpProcessInformation
  1416. ));
  1417. }
  1418. End=
  1419. [EFunc]
  1420. TemplateName=CreateStdAccessibleProxyW
  1421. Begin=
  1422. HRESULT __stdcall
  1423. GodotCreateStdAccessibleProxyW(HWND hwnd, LPCWSTR pClassName, LONG idObject, const IID * riid, void ** ppv)
  1424. {
  1425. HRESULT RetVal = E_NOTIMPL;
  1426. if (s_pfnCreateStdAccessibleProxy == NULL)
  1427. {
  1428. // Must allocate stuff for this API call
  1429. s_pfnCreateStdAccessibleProxy = (PFNcsapa)GetOleAccProc("CreateStdAccessibleProxyA");
  1430. }
  1431. if (s_pfnCreateStdAccessibleProxy)
  1432. {
  1433. LPSTR pClassNameAnsi;
  1434. GODOT_TO_ACP_STACKALLOC(pClassName, pClassNameAnsi);
  1435. if(!pClassNameAnsi && pClassName)
  1436. return(E_FAIL);
  1437. RetVal = (s_pfnCreateStdAccessibleProxy(hwnd, pClassNameAnsi, idObject, riid, ppv));
  1438. }
  1439. else
  1440. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1441. return RetVal;
  1442. }
  1443. End=
  1444. [EFunc]
  1445. TemplateName=CreateWindowExW
  1446. Begin=
  1447. HWND __stdcall
  1448. GodotCreateWindowExW( DWORD dwExStyle,
  1449. LPCWSTR lpClassName,
  1450. LPCWSTR lpWindowName,
  1451. DWORD dwStyle,
  1452. int X,
  1453. int Y,
  1454. int nWidth,
  1455. int nHeight,
  1456. HWND hWndParent,
  1457. HMENU hMenu,
  1458. HINSTANCE hInstance,
  1459. LPVOID lpParam
  1460. )
  1461. {
  1462. // Begin locals
  1463. HWND RetVal;
  1464. LPSTR lpClassNameAnsi = NULL;
  1465. LPSTR lpWindowNameAnsi = NULL;
  1466. LPGODOTTLSINFO lpgti = GetThreadInfoSafe(TRUE);
  1467. GODOT_TO_ACP_STACKALLOC(lpClassName, lpClassNameAnsi);
  1468. GODOT_TO_ACP_STACKALLOC(lpWindowName, lpWindowNameAnsi);
  1469. if(!lpgti ||
  1470. (!lpClassNameAnsi && lpClassName) ||
  1471. (!lpWindowNameAnsi && lpWindowName))
  1472. return(0);
  1473. INIT_WINDOW_SNIFF(lpgti->hHook);
  1474. RetVal=CreateWindowExA(dwExStyle,
  1475. lpClassNameAnsi,
  1476. lpWindowNameAnsi,
  1477. dwStyle,
  1478. X,
  1479. Y,
  1480. nWidth,
  1481. nHeight,
  1482. hWndParent,
  1483. hMenu,
  1484. hInstance,
  1485. lpParam
  1486. );
  1487. TERM_WINDOW_SNIFF(lpgti->hHook);
  1488. // Finished
  1489. return RetVal;
  1490. }
  1491. End=
  1492. [EFunc]
  1493. TemplateName=CreateWaitableTimerW
  1494. Begin=
  1495. HANDLE __stdcall
  1496. GodotCreateWaitableTimerW(LPSECURITY_ATTRIBUTES lpTimerAttributes, BOOL bManualReset, LPCWSTR lpTimerName)
  1497. {
  1498. // Begin locals
  1499. HANDLE RetVal = NULL;
  1500. if (s_pfnCreateWaitableTimerA == NULL)
  1501. {
  1502. // Must allocate stuff for this API call
  1503. s_pfnCreateWaitableTimerA = (PFNcwta)GetKernelProc("CreateWaitableTimerA");
  1504. }
  1505. if (s_pfnCreateWaitableTimerA)
  1506. {
  1507. LPSTR lpTimerNameAnsi;
  1508. GODOT_TO_ACP_STACKALLOC(lpTimerName, lpTimerNameAnsi);
  1509. RetVal = (s_pfnCreateWaitableTimerA(lpTimerAttributes, bManualReset, lpTimerNameAnsi));
  1510. }
  1511. else
  1512. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1513. // Finished
  1514. return RetVal;
  1515. }
  1516. End=
  1517. [EFunc]
  1518. TemplateName=DdeConnect
  1519. Begin=
  1520. HCONV __stdcall
  1521. GodotDdeConnect(DWORD idInst, HSZ hszService, HSZ hszTopic, PCONVCONTEXT pCC)
  1522. {
  1523. if(pCC)
  1524. {
  1525. // CP_WINUNICODE is not a valid param for Win95/98/ME, so
  1526. // we will munge it here it it exists. Nothing else needs to
  1527. // change
  1528. if(pCC->iCodePage == CP_WINUNICODE)
  1529. pCC->iCodePage = CP_WINANSI;
  1530. }
  1531. return(DdeConnect(idInst, hszService, hszTopic, pCC));
  1532. }
  1533. End=
  1534. [EFunc]
  1535. TemplateName=DdeConnectList
  1536. Begin=
  1537. HCONVLIST __stdcall
  1538. GodotDdeConnectList(DWORD idInst, HSZ hszService, HSZ hszTopic, HCONVLIST hConvList, PCONVCONTEXT pCC)
  1539. {
  1540. if(pCC)
  1541. {
  1542. // CP_WINUNICODE is not a valid param for Win95/98/ME, so
  1543. // we will munge it here it it exists. Nothing else needs to
  1544. // change
  1545. if(pCC->iCodePage == CP_WINUNICODE)
  1546. pCC->iCodePage = CP_WINANSI;
  1547. }
  1548. return(DdeConnectList(idInst, hszService, hszTopic, hConvList, pCC));
  1549. }
  1550. End=
  1551. [EFunc]
  1552. TemplateName=DdeCreateStringHandleW
  1553. Begin=
  1554. HSZ __stdcall
  1555. GodotDdeCreateStringHandleW(DWORD idInst, LPCWSTR psz, int iCodePage)
  1556. {
  1557. // Begin locals
  1558. HSZ RetVal;
  1559. LPSTR pszAnsi;
  1560. if(iCodePage == CP_WINUNICODE)
  1561. {
  1562. GODOT_TO_ACP_STACKALLOC(psz, pszAnsi);
  1563. if(pszAnsi==NULL)
  1564. {
  1565. RetVal = 0L;
  1566. }
  1567. RetVal=DdeCreateStringHandleA(idInst, pszAnsi, iCodePage);
  1568. }
  1569. else if((iCodePage == CP_WINANSI) || // This is what the docs say it must be
  1570. (iCodePage == (int)GetACP()) || // Turns out it can be this,
  1571. (iCodePage == (int)GetOEMCP())) // and it can also be this
  1572. {
  1573. // No conversion needed
  1574. RetVal=DdeCreateStringHandleA(idInst, (LPSTR)psz, iCodePage);
  1575. }
  1576. else
  1577. {
  1578. SetLastError(ERROR_INVALID_PARAMETER);
  1579. RetVal = 0L;
  1580. }
  1581. // Finished
  1582. return RetVal;
  1583. }
  1584. End=
  1585. [EFunc]
  1586. TemplateName=DdeInitializeW
  1587. Begin=
  1588. UINT __stdcall
  1589. GodotDdeInitializeW(LPDWORD pidInst, PFNCALLBACK pfnCallback, DWORD afCmd, DWORD ulRes)
  1590. {
  1591. // CONSIDER: Several DDE messages might not have the right iCodePage flag in them:
  1592. // XTYP_CONNECT - CONVCONTEXT in dwData1
  1593. // XTYP_WILDCONNECT - CONVCONTEXT in dwData1
  1594. // XTYP_MONITOR - several potential structures that do this
  1595. return(DdeInitializeA(pidInst, pfnCallback, afCmd, ulRes));
  1596. }
  1597. End=
  1598. [EFunc]
  1599. TemplateName=DdeQueryConvInfo
  1600. Begin=
  1601. UINT __stdcall
  1602. GodotDdeQueryConvInfo(HCONV hConv, DWORD idTransaction, PCONVINFO pConvInfo)
  1603. {
  1604. UINT RetVal;
  1605. BOOL fUnicode = FALSE;
  1606. // Munge the structure if it is there to fix up CP_WINUNICODE refs
  1607. if(pConvInfo)
  1608. {
  1609. if(pConvInfo->ConvCtxt.iCodePage == CP_WINUNICODE)
  1610. {
  1611. fUnicode = TRUE;
  1612. pConvInfo->ConvCtxt.iCodePage = CP_WINANSI;
  1613. }
  1614. }
  1615. // Call the API
  1616. RetVal=DdeQueryConvInfo(hConv, idTransaction, pConvInfo);
  1617. // Fix the structure back if we mucked with it
  1618. if(fUnicode)
  1619. pConvInfo->ConvCtxt.iCodePage = CP_WINUNICODE;
  1620. // Finished
  1621. return RetVal;
  1622. }
  1623. End=
  1624. [EFunc]
  1625. TemplateName=DdeQueryStringW
  1626. Begin=
  1627. DWORD __stdcall
  1628. GodotDdeQueryStringW(DWORD idInst, HSZ hsz, LPWSTR psz, DWORD cchMax, int iCodePage)
  1629. {
  1630. // Begin locals
  1631. DWORD RetVal;
  1632. LPSTR pszAnsi;
  1633. if(iCodePage == CP_WINUNICODE)
  1634. {
  1635. if(psz)
  1636. {
  1637. _STACKALLOC(cchMax*g_mcs, pszAnsi);
  1638. }
  1639. else
  1640. pszAnsi = NULL;
  1641. RetVal=DdeQueryStringA(idInst, hsz, pszAnsi, cchMax, CP_WINANSI);
  1642. if(psz && pszAnsi)
  1643. {
  1644. MultiByteToWideChar(g_acp, 0, pszAnsi, cchMax*g_mcs, psz, cchMax);
  1645. RetVal = gwcslen(psz);
  1646. }
  1647. else
  1648. {
  1649. // We have been given a return that the PSDK claims is ANSI TCHARs. This
  1650. // count should match the Unicode cch so we can leave it alone.
  1651. }
  1652. }
  1653. else if((iCodePage == CP_WINANSI) || // This is what the docs say it must be
  1654. (iCodePage == (int)GetACP()) || // Turns out it can be this,
  1655. (iCodePage == (int)GetOEMCP())) // and it can also be this
  1656. {
  1657. // Not doing a Unicode code page, so no conversion needed or wanted
  1658. RetVal=DdeQueryStringA(idInst, hsz, (LPSTR)psz, cchMax, iCodePage);
  1659. }
  1660. else
  1661. {
  1662. SetLastError(ERROR_INVALID_PARAMETER);
  1663. RetVal = 0L;
  1664. }
  1665. return RetVal;
  1666. }
  1667. End=
  1668. [EFunc]
  1669. TemplateName=DefDlgProcW
  1670. Begin=
  1671. LRESULT __stdcall
  1672. GodotDefDlgProcW(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
  1673. {
  1674. return(GodotTransmitMessage(mtDefDlgProc, hDlg, Msg, wParam, lParam, 0, 0, 0, 0, 0, 0));
  1675. }
  1676. End=
  1677. [EFunc]
  1678. TemplateName=DefFrameProcW
  1679. Begin=
  1680. LRESULT __stdcall
  1681. GodotDefFrameProcW(HWND hWnd, HWND hWndMDIClient, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1682. {
  1683. // Overloading GTM's dwData param for hWndMDIClient
  1684. return(GodotTransmitMessage(mtDefFrameProc, hWnd, uMsg, wParam,
  1685. lParam, 0, 0, (DWORD)hWndMDIClient, 0, 0, 0));
  1686. }
  1687. End=
  1688. [EFunc]
  1689. TemplateName=DefMDIChildProcW
  1690. Begin=
  1691. LRESULT __stdcall
  1692. GodotDefMDIChildProcW(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1693. {
  1694. return(GodotTransmitMessage(mtDefMDIChildProc, hWnd, uMsg, wParam, lParam, 0, 0, 0, 0, 0, 0));
  1695. }
  1696. End=
  1697. [EFunc]
  1698. TemplateName=DefWindowProcW
  1699. Begin=
  1700. LRESULT __stdcall
  1701. GodotDefWindowProcW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  1702. {
  1703. return(GodotTransmitMessage(mtDefWindowProc, hWnd, Msg, wParam, lParam, 0, 0, 0, 0, 0, 0));
  1704. }
  1705. End=
  1706. [EFunc]
  1707. TemplateName=DeleteFileW
  1708. Begin=
  1709. BOOL __stdcall
  1710. GodotDeleteFileW(LPCWSTR lpFileName)
  1711. {
  1712. LPSTR lpFileNameAnsi;
  1713. GODOT_TO_CPG_STACKALLOC(lpFileName, lpFileNameAnsi, FILES_CPG, g_mcs);
  1714. return(DeleteFileA(lpFileNameAnsi));
  1715. }
  1716. End=
  1717. [EFunc]
  1718. TemplateName=DeleteMinitorW
  1719. Begin=
  1720. BOOL __stdcall GodotDeleteMonitorW(LPWSTR pName, LPWSTR pEnvironment, LPWSTR pMonitorName)
  1721. {
  1722. BOOL RetVal = FALSE;
  1723. LPSTR pNameAnsi = NULL;
  1724. LPSTR pEnvironmentAnsi = NULL;
  1725. LPSTR pMonitorNameAnsi = NULL;
  1726. ALLOCRETURN arName = GodotToAcpOnHeap(pName, &pNameAnsi);
  1727. ALLOCRETURN arEnvironmentName = GodotToAcpOnHeap(pEnvironment, &pEnvironmentAnsi);
  1728. ALLOCRETURN arMonitorName = GodotToAcpOnHeap(pMonitorName, &pMonitorNameAnsi);
  1729. if(arName != arFailed && arEnvironmentName != arFailed && arMonitorName != arFailed)
  1730. RetVal=DeleteMonitorWA(pNameAnsi, pEnvironmentAnsi, pMonitorNameAnsi);
  1731. if(arName==arAlloc)
  1732. GodotHeapFree(pNameAnsi);
  1733. if(arEnvironmentName==arAlloc)
  1734. GodotHeapFree(pEnvironmentAnsi);
  1735. if(arMonitorName==arAlloc)
  1736. GodotHeapFree(pMonitorNameAnsi);
  1737. if(arName == arFailed || arEnvironmentName == arFailed || arMonitorName == arFailed)
  1738. SetLastError(ERROR_OUTOFMEMORY);
  1739. return RetVal;
  1740. }
  1741. End=
  1742. [EFunc]
  1743. TemplateName=DeletePortW
  1744. Begin=
  1745. BOOL __stdcall GodotDeletePortW(LPWSTR pName, HWND hWnd, LPWSTR pPortName)
  1746. {
  1747. BOOL RetVal = FALSE;
  1748. LPSTR pNameAnsi = NULL;
  1749. LPSTR pPortNameAnsi = NULL;
  1750. ALLOCRETURN arName = GodotToAcpOnHeap(pName, &pNameAnsi);
  1751. ALLOCRETURN arPortName = GodotToAcpOnHeap(pPortName, &pPortNameAnsi);
  1752. if(arName != arFailed && arPortName != arFailed)
  1753. RetVal = DeletePortA(pNameAnsi, hWnd, pPortNameAnsi);
  1754. if(arName==arAlloc)
  1755. GodotHeapFree(pNameAnsi);
  1756. if(arPortName==arAlloc)
  1757. GodotHeapFree(pPortNameAnsi);
  1758. if(arName == arFailed || arPortName == arFailed)
  1759. SetLastError(ERROR_OUTOFMEMORY);
  1760. return(RetVal);
  1761. }
  1762. End=
  1763. [EFunc]
  1764. TemplateName=DeletePrinterDriverW
  1765. Begin=
  1766. BOOL __stdcall
  1767. GodotDeletePrinterDriverW(LPWSTR pName, LPWSTR pEnvironment, LPWSTR pDriverName)
  1768. {
  1769. BOOL RetVal = FALSE;
  1770. LPSTR pNameAnsi = NULL;
  1771. LPSTR pEnvironmentAnsi = NULL;
  1772. LPSTR pDriverNameAnsi = NULL;
  1773. ALLOCRETURN arName = GodotToAcpOnHeap(pName, &pNameAnsi);
  1774. ALLOCRETURN arEnvironmentName = GodotToAcpOnHeap(pEnvironment, &pEnvironmentAnsi);
  1775. ALLOCRETURN arDriverName = GodotToAcpOnHeap(pDriverName, &pDriverNameAnsi);
  1776. if(arName != arFailed && arEnvironmentName != arFailed && arDriverName != arFailed)
  1777. RetVal = DeletePrinterDriverA(pNameAnsi, pEnvironmentAnsi, pDriverNameAnsi);
  1778. if(arName==arAlloc)
  1779. GodotHeapFree(pNameAnsi);
  1780. if(arEnvironmentName==arAlloc)
  1781. GodotHeapFree(pEnvironmentAnsi);
  1782. if(arDriverName==arAlloc)
  1783. GodotHeapFree(pDriverNameAnsi);
  1784. if(arName == arFailed || arEnvironmentName == arFailed || arDriverName == arFailed)
  1785. SetLastError(ERROR_OUTOFMEMORY);
  1786. return(RetVal);
  1787. }
  1788. End=
  1789. [EFunc]
  1790. TemplateName=DeletePrintProcessorW
  1791. Begin=
  1792. BOOL __stdcall
  1793. GodotDeletePrintProcessorW(LPWSTR pName, LPWSTR pEnvironment, LPWSTR pPrintProcessorName)
  1794. {
  1795. BOOL RetVal = FALSE;
  1796. LPSTR pNameAnsi = NULL;
  1797. LPSTR pEnvironmentAnsi = NULL;
  1798. LPSTR pPrintProcessorNameAnsi = NULL;
  1799. ALLOCRETURN arName = GodotToAcpOnHeap(pName, &pNameAnsi);
  1800. ALLOCRETURN arEnvironmentName = GodotToAcpOnHeap(pEnvironment, &pEnvironmentAnsi);
  1801. ALLOCRETURN arProcessorName = GodotToAcpOnHeap(pPrintProcessorName, &pPrintProcessorNameAnsi);
  1802. if(arName != arFailed && arEnvironmentName != arFailed && arProcessorName != arFailed)
  1803. RetVal = DeletePrintProcessorA(pNameAnsi, pEnvironmentAnsi, pPrintProcessorNameAnsi);
  1804. if(arName==arAlloc)
  1805. GodotHeapFree(pNameAnsi);
  1806. if(arEnvironmentName==arAlloc)
  1807. GodotHeapFree(pEnvironmentAnsi);
  1808. if(arProcessorName==arAlloc)
  1809. GodotHeapFree(pPrintProcessorNameAnsi);
  1810. if(arName == arFailed || arEnvironmentName == arFailed || arProcessorName == arFailed)
  1811. SetLastError(ERROR_OUTOFMEMORY);
  1812. return(RetVal);
  1813. }
  1814. End=
  1815. [EFunc]
  1816. TemplateName=DeletePrintProvidorW
  1817. Begin=
  1818. BOOL __stdcall GodotDeletePrintProvidorW(LPWSTR pName, LPWSTR pEnvironment, LPWSTR pPrintProvidorName)
  1819. {
  1820. BOOL RetVal = FALSE;
  1821. LPSTR pNameAnsi = NULL;
  1822. LPSTR pEnvironmentAnsi = NULL;
  1823. LPSTR pPrintProvidorNameAnsi = NULL;
  1824. ALLOCRETURN arName = GodotToAcpOnHeap(pName, &pNameAnsi);
  1825. ALLOCRETURN arEnvironmentName = GodotToAcpOnHeap(pEnvironment, &pEnvironmentAnsi);
  1826. ALLOCRETURN arPrintProvidorName = GodotToAcpOnHeap(pPrintProvidorName, &pPrintProvidorNameAnsi);
  1827. if(arName != arFailed && arEnvironmentName != arFailed && arPrintProvidorName != arFailed)
  1828. RetVal=DeletePrintProvidorWA(pNameAnsi, pEnvironmentAnsi, pPrintProvidorNameAnsi);
  1829. if(arName==arAlloc)
  1830. GodotHeapFree(pNameAnsi);
  1831. if(arEnvironmentName==arAlloc)
  1832. GodotHeapFree(pEnvironmentAnsi);
  1833. if(arPrintProvidorName==arAlloc)
  1834. GodotHeapFree(pPrintProvidorNameAnsi);
  1835. if(arName == arFailed || arEnvironmentName == arFailed || arPrintProvidorName == arFailed)
  1836. SetLastError(ERROR_OUTOFMEMORY);
  1837. return(RetVal);
  1838. }
  1839. End=
  1840. [EFunc]
  1841. TemplateName=DeviceCapabilitiesW
  1842. Begin=
  1843. int __stdcall
  1844. GodotDeviceCapabilitiesW(LPCWSTR pDevice, LPCWSTR pPort, WORD fwCapability, LPWSTR pOutput,
  1845. const DEVMODEW * pDevMode)
  1846. {
  1847. // UNSUPPORTED FUNCTION: Documented as a failure stub
  1848. LPCSTR pDeviceAnsi;
  1849. LPCSTR pPortAnsi;
  1850. int RetVal;
  1851. LPDEVMODEA pdma;
  1852. GODOT_TO_ACP_STACKALLOC(pDevice, pDeviceAnsi);
  1853. GODOT_TO_ACP_STACKALLOC(pPort, pPortAnsi);
  1854. if((pDeviceAnsi==NULL && pDevice != NULL) ||
  1855. (pPortAnsi==NULL && pPort != NULL))
  1856. {
  1857. return(0);
  1858. }
  1859. if(pDevMode==NULL)
  1860. pdma = NULL;
  1861. else
  1862. {
  1863. pdma = GodotHeapAlloc(sizeof(DEVMODEA) + pDevMode->dmDriverExtra);
  1864. if(pdma==NULL)
  1865. {
  1866. SetLastError(ERROR_OUTOFMEMORY);
  1867. return(0);
  1868. }
  1869. DevModeAfromW(pdma, (LPDEVMODEW)pDevMode);
  1870. }
  1871. switch(fwCapability)
  1872. {
  1873. case DC_BINNAMES:
  1874. case DC_PAPERNAMES:
  1875. case DC_FILEDEPENDENCIES:
  1876. {
  1877. // Array of 24-char or 64-char strings, RetVal is the number of them
  1878. // The strings are null-terminated unless the name is 64 characters long.
  1879. // Always get the size, either because that is all
  1880. // the caller wanted or because we need it ourselves.
  1881. RetVal = DeviceCapabilitiesA(pDeviceAnsi, pPortAnsi, fwCapability, NULL, pdma);
  1882. if(pOutput!=NULL)
  1883. {
  1884. LPSTR pOutputAnsi;
  1885. size_t cchBuf = ((fwCapability==DC_BINNAMES ? 24 : 64) * RetVal);
  1886. _STACKALLOC((cchBuf * RetVal), pOutputAnsi);
  1887. if(pOutputAnsi==NULL)
  1888. {
  1889. if(pdma)
  1890. GodotHeapFree(pdma);
  1891. return(0);
  1892. }
  1893. RetVal = DeviceCapabilitiesA(pDeviceAnsi, pPortAnsi, fwCapability, pOutputAnsi, pdma);
  1894. if(RetVal > 0)
  1895. {
  1896. // Failure is -1 and 0 means nothing to convert so this
  1897. // is a good conditional for the conversion.
  1898. MultiByteToWideChar(g_acp, 0, pOutputAnsi, cchBuf, pOutput, cchBuf);
  1899. }
  1900. }
  1901. break;
  1902. }
  1903. case DC_BINS:
  1904. case DC_ENUMRESOLUTIONS:
  1905. case DC_PAPERS:
  1906. case DC_PAPERSIZE:
  1907. // Output param is an array of values (LONG or WORD or POINT)
  1908. // CONSIDER: Why bother will a special case here?
  1909. RetVal = DeviceCapabilitiesA(pDeviceAnsi, pPortAnsi, fwCapability, (LPSTR)pOutput, pdma);
  1910. break;
  1911. default:
  1912. // Output param is not used
  1913. RetVal = DeviceCapabilitiesA(pDeviceAnsi, pPortAnsi, fwCapability, (LPSTR)pOutput, pdma);
  1914. break;
  1915. }
  1916. if(pdma)
  1917. GodotHeapFree(pdma);
  1918. return(RetVal);
  1919. }
  1920. End=
  1921. [EFunc]
  1922. TemplateName=DialogBoxIndirectParamW
  1923. Begin=
  1924. INT_PTR __stdcall
  1925. GodotDialogBoxIndirectParamW(HINSTANCE hInst, LPCDLGTEMPLATEW hdt, HWND hWnd, DLGPROC lpfn, LPARAM dwParam)
  1926. {
  1927. LPGODOTTLSINFO lpgti = GetThreadInfoSafe(TRUE);
  1928. if(!lpgti)
  1929. {
  1930. SetLastError(ERROR_OUTOFMEMORY);
  1931. return(0);
  1932. }
  1933. else
  1934. {
  1935. INT_PTR RetVal;
  1936. INIT_WINDOW_SNIFF(lpgti->hHook);
  1937. lpgti->pfnDlgProc = lpfn;
  1938. RetVal = DialogBoxIndirectParamA(hInst, (LPCDLGTEMPLATEA)hdt, hWnd, &DialogProc, dwParam);
  1939. TERM_WINDOW_SNIFF(lpgti->hHook);
  1940. return(RetVal);
  1941. }
  1942. }
  1943. End=
  1944. [EFunc]
  1945. TemplateName=DialogBoxParamW
  1946. Begin=
  1947. INT_PTR __stdcall
  1948. GodotDialogBoxParamW(HINSTANCE hInst, LPCWSTR lpTemplate, HWND hWndParent, DLGPROC lpfn, LPARAM dwParam)
  1949. {
  1950. LPGODOTTLSINFO lpgti = GetThreadInfoSafe(TRUE);
  1951. if(!lpgti)
  1952. {
  1953. SetLastError(ERROR_OUTOFMEMORY);
  1954. return(0);
  1955. }
  1956. else
  1957. {
  1958. INT_PTR RetVal;
  1959. LPSTR lpTemplateAnsi;
  1960. GODOT_TO_ACP_STACKALLOC(lpTemplate, lpTemplateAnsi);
  1961. lpgti->pfnDlgProc = lpfn;
  1962. INIT_WINDOW_SNIFF(lpgti->hHook);
  1963. RetVal=DialogBoxParamA(hInst, lpTemplateAnsi, hWndParent, &DialogProc, dwParam);
  1964. TERM_WINDOW_SNIFF(lpgti->hHook);
  1965. return RetVal;
  1966. }
  1967. }
  1968. End=
  1969. [EFunc]
  1970. TemplateName=DispatchMessageW
  1971. Begin=
  1972. LRESULT __stdcall
  1973. GodotDispatchMessageW(const MSG * lpMsg)
  1974. {
  1975. return(GodotDispatchMessage(mtDispatchMessage, NULL, NULL, (LPMSG)lpMsg));
  1976. }
  1977. End=
  1978. [EFunc]
  1979. TemplateName=DlgDirListW
  1980. Begin=
  1981. int __stdcall
  1982. GodotDlgDirListW(HWND hDlg, LPWSTR lpPathSpec, int nIDListBox, int nIDStaticPath, UINT uFileType)
  1983. {
  1984. // Begin locals
  1985. int RetVal;
  1986. LPSTR lpPathSpecAnsi;
  1987. // Begin precall
  1988. GODOT_TO_ACP_STACKALLOC(lpPathSpec, lpPathSpecAnsi);
  1989. RetVal=DlgDirListA(hDlg, lpPathSpecAnsi, nIDListBox, nIDStaticPath, uFileType);
  1990. if(RetVal)
  1991. MultiByteToWideChar(g_acp, 0, lpPathSpecAnsi, -1, lpPathSpec, gwcslen(lpPathSpec));
  1992. // Finished
  1993. return RetVal;
  1994. }
  1995. End=
  1996. [EFunc]
  1997. TemplateName=DlgDirListComboBoxW
  1998. Begin=
  1999. int __stdcall
  2000. GodotDlgDirListComboBoxW(HWND hDlg, LPWSTR lpPathSpec, int nIDComboBox, int nIDStaticPath, UINT uFiletype)
  2001. {
  2002. // Begin locals
  2003. int RetVal;
  2004. LPSTR lpPathSpecAnsi;
  2005. // Begin precall
  2006. GODOT_TO_ACP_STACKALLOC(lpPathSpec, lpPathSpecAnsi);
  2007. RetVal=DlgDirListComboBoxA(hDlg, lpPathSpecAnsi, nIDComboBox, nIDStaticPath, uFiletype);
  2008. if(RetVal)
  2009. MultiByteToWideChar(g_acp, 0, lpPathSpecAnsi, -1, lpPathSpec, gwcslen(lpPathSpec));
  2010. // Finished
  2011. return RetVal;
  2012. }
  2013. End=
  2014. [EFunc]
  2015. TemplateName=DlgDirSelectComboBoxExW
  2016. Begin=
  2017. BOOL __stdcall
  2018. GodotDlgDirSelectComboBoxExW(HWND hDlg, LPWSTR lpString, int nCount, int nIDComboBox)
  2019. {
  2020. BOOL RetVal;
  2021. LPSTR lpStringAnsi;
  2022. _STACKALLOC((nCount * g_mcs) + 1, lpStringAnsi);
  2023. if(!lpStringAnsi)
  2024. return(FALSE);
  2025. RetVal=DlgDirSelectComboBoxExA(hDlg, lpStringAnsi, nCount, nIDComboBox);
  2026. if(FSTRING_VALID(lpString) && FSTRING_VALID(lpStringAnsi))
  2027. MultiByteToWideChar(g_acp, 0, lpStringAnsi, -1, lpString, nCount);
  2028. else if(FSTRING_VALID(lpString))
  2029. {
  2030. lpString[0] = '\0';
  2031. }
  2032. return RetVal;
  2033. }
  2034. End=
  2035. [EFunc]
  2036. TemplateName=DlgDirSelectExW
  2037. Begin=
  2038. BOOL __stdcall
  2039. GodotDlgDirSelectExW(HWND hDlg, LPWSTR lpString, int nCount, int nIDListBox)
  2040. {
  2041. BOOL RetVal;
  2042. LPSTR lpStringAnsi;
  2043. _STACKALLOC((nCount * g_mcs) + 1, lpStringAnsi);
  2044. if(!lpStringAnsi)
  2045. {
  2046. SetLastError(ERROR_STACK_OVERFLOW);
  2047. return(FALSE);
  2048. }
  2049. RetVal=DlgDirSelectExA(hDlg, lpStringAnsi, nCount, nIDListBox);
  2050. if(FSTRING_VALID(lpString) && FSTRING_VALID(lpStringAnsi))
  2051. MultiByteToWideChar(g_acp, 0, lpStringAnsi, -1, lpString, nCount);
  2052. else if(FSTRING_VALID(lpString))
  2053. {
  2054. lpString[0] = '\0';
  2055. }
  2056. return RetVal;
  2057. }
  2058. End=
  2059. [EFunc]
  2060. TemplateName=DocumentPropertiesW
  2061. Begin=
  2062. LONG __stdcall
  2063. GodotDocumentPropertiesW(HWND hWnd, HANDLE hPrinter, LPWSTR pDeviceName,
  2064. PDEVMODEW pDevModeOutput, PDEVMODEW pDevModeInput, DWORD fMode)
  2065. {
  2066. // UNSUPPORTED FUNCTION: Documented as a failure stub
  2067. LPDEVMODEA lpdmaOut = NULL;
  2068. LPDEVMODEA lpdmaIn = NULL;
  2069. LONG RetVal = 0;
  2070. LPSTR pDeviceNameAnsi = NULL;
  2071. ALLOCRETURN arDeviceName = GodotToAcpOnHeap(pDeviceName, &pDeviceNameAnsi);
  2072. if(arDeviceName==arFailed)
  2073. {
  2074. SetLastError(ERROR_OUTOFMEMORY);
  2075. return(0);
  2076. }
  2077. if((fMode & DM_OUT_BUFFER) && pDevModeOutput)
  2078. {
  2079. LONG cb = DocumentPropertiesA(hWnd, hPrinter, pDeviceNameAnsi, NULL, NULL, 0);
  2080. _STACKALLOC(cb, lpdmaOut);
  2081. if(!lpdmaOut && (cb > 0))
  2082. {
  2083. if(arDeviceName==arAlloc)
  2084. GodotHeapFree(pDeviceNameAnsi);
  2085. return(0);
  2086. }
  2087. }
  2088. if((fMode & DM_IN_BUFFER) && pDevModeInput)
  2089. {
  2090. lpdmaIn = GodotHeapAlloc(sizeof(DEVMODEA) + (pDevModeInput ? pDevModeInput->dmDriverExtra : 0));
  2091. if(lpdmaIn==NULL)
  2092. {
  2093. if(arDeviceName==arAlloc)
  2094. GodotHeapFree(pDeviceNameAnsi);
  2095. return(0);
  2096. }
  2097. ZeroMemory(lpdmaIn, sizeof(DEVMODEA) + (pDevModeInput ? pDevModeInput->dmDriverExtra : 0));
  2098. DevModeAfromW(lpdmaIn, pDevModeInput);
  2099. }
  2100. RetVal = DocumentPropertiesA(hWnd, hPrinter, pDeviceNameAnsi, lpdmaOut, lpdmaIn, fMode);
  2101. if(fMode == 0)
  2102. {
  2103. // More accurate calculation of the DEVMODE size to return
  2104. RetVal += sizeof(DEVMODEW) - sizeof(DEVMODEA);
  2105. }
  2106. else if(RetVal==IDOK && (fMode & DM_OUT_BUFFER))
  2107. {
  2108. DevModeWfromA(pDevModeOutput, lpdmaOut);
  2109. }
  2110. if(arDeviceName==arAlloc)
  2111. GodotHeapFree(pDeviceNameAnsi);
  2112. if(lpdmaIn)
  2113. GodotHeapFree(lpdmaIn);
  2114. return(RetVal);
  2115. }
  2116. End=
  2117. [EFunc]
  2118. TemplateName=DragQueryFileW
  2119. Begin=
  2120. UINT __stdcall
  2121. GodotDragQueryFileW(HDROP hDrop, UINT iFile, LPWSTR lpszFile, UINT cch)
  2122. {
  2123. UINT RetVal;
  2124. if(iFile != 0xFFFFFFFF)
  2125. {
  2126. LPSTR lpszFileAnsi;
  2127. if(lpszFile)
  2128. {
  2129. _STACKALLOC(cch * g_mcs, lpszFileAnsi);
  2130. if(lpszFileAnsi==NULL)
  2131. {
  2132. return(0);
  2133. }
  2134. ZeroMemory(lpszFileAnsi, cch * g_mcs);
  2135. }
  2136. else
  2137. lpszFileAnsi = NULL;
  2138. RetVal=DragQueryFileA(hDrop, iFile, lpszFileAnsi, cch);
  2139. if((RetVal > 0) && (lpszFile))
  2140. MultiByteToWideChar(g_acp, 0, lpszFileAnsi, -1, lpszFile, cch);
  2141. }
  2142. else
  2143. {
  2144. RetVal=DragQueryFileA(hDrop, iFile, (LPSTR)lpszFile, cch);
  2145. }
  2146. return RetVal;
  2147. }
  2148. End=
  2149. [EFunc]
  2150. TemplateName=DrawTextW
  2151. Begin=
  2152. int __stdcall
  2153. GodotDrawTextW(HDC hDC, LPCWSTR lpString, int nCount, LPRECT lpRect, UINT uFormat)
  2154. {
  2155. int RetVal;
  2156. LPSTR lpStringAnsi;
  2157. BOOL fExtra =((uFormat & DT_MODIFYSTRING) &&
  2158. (uFormat & (DT_PATH_ELLIPSIS | DT_WORD_ELLIPSIS | DT_END_ELLIPSIS)));
  2159. int Adj = (fExtra ? 4 : 0);
  2160. UINT cpg = CpgFromHdc(hDC);
  2161. UINT mcs = CbPerChOfCpg(cpg);
  2162. if (FSTRING_VALID(lpString))
  2163. {
  2164. size_t lpStringLength = gwcslen(lpString) + 1;
  2165. _STACKALLOC((lpStringLength+Adj)*mcs, lpStringAnsi);
  2166. if(lpStringAnsi==NULL)
  2167. {
  2168. return(0);
  2169. }
  2170. WideCharToMultiByte(cpg, 0,
  2171. lpString, lpStringLength,
  2172. lpStringAnsi, (lpStringLength+Adj)*mcs,
  2173. NULL, NULL);
  2174. }
  2175. else
  2176. lpStringAnsi = (LPSTR)lpString;
  2177. RetVal=DrawTextA(hDC, lpStringAnsi, nCount, lpRect, uFormat);
  2178. // Note that lpString is only modified if fExtraChars is True
  2179. if (RetVal && fExtra)
  2180. MultiByteToWideChar(cpg, 0, lpStringAnsi, -1, (LPWSTR)lpString, (gwcslen(lpString) + Adj));
  2181. return RetVal;
  2182. }
  2183. End=
  2184. [EFunc]
  2185. TemplateName=DrawTextExW
  2186. Begin=
  2187. int __stdcall
  2188. GodotDrawTextExW( HDC hdc,
  2189. LPWSTR lpchText,
  2190. int cchText,
  2191. LPRECT lprc,
  2192. UINT dwDTF,
  2193. LPDRAWTEXTPARAMS lpDTParams
  2194. )
  2195. {
  2196. int RetVal;
  2197. LPSTR lpchTextAnsi;
  2198. BOOL fExtra =((dwDTF & DT_MODIFYSTRING) &&
  2199. (dwDTF & (DT_PATH_ELLIPSIS | DT_WORD_ELLIPSIS | DT_END_ELLIPSIS)));
  2200. int Adj = (fExtra ? 4 : 0);
  2201. UINT cpg = CpgFromHdc(hdc);
  2202. UINT mcs = CbPerChOfCpg(cpg);
  2203. if (FSTRING_VALID(lpchText))
  2204. {
  2205. size_t lpchTextAnsiLength = gwcslen(lpchText) + 1;
  2206. _STACKALLOC((lpchTextAnsiLength+Adj)*mcs, lpchTextAnsi);
  2207. if(lpchTextAnsi==NULL)
  2208. {
  2209. return(0);
  2210. }
  2211. WideCharToMultiByte(cpg, 0,
  2212. lpchText, lpchTextAnsiLength,
  2213. lpchTextAnsi, (lpchTextAnsiLength+Adj)*mcs,
  2214. NULL, NULL);
  2215. }
  2216. else
  2217. lpchTextAnsi = (LPSTR)lpchText;
  2218. RetVal=DrawTextExA(hdc, lpchTextAnsi, cchText, lprc, dwDTF, lpDTParams);
  2219. // Note that lpString is only modified if fExtraChars is True
  2220. if (RetVal && fExtra)
  2221. MultiByteToWideChar(cpg, 0, lpchTextAnsi, -1, (LPWSTR)lpchText, (gwcslen(lpchText) + Adj));
  2222. return RetVal;
  2223. }
  2224. End=
  2225. [EFunc]
  2226. TemplateName=EnableWindow
  2227. Begin=
  2228. BOOL __stdcall
  2229. GodotEnableWindow(HWND hWnd, BOOL bEnable)
  2230. {
  2231. // We wrap this API in order to get consistent behavior on both
  2232. // NT and Win9x. It seems that on NT, any non-zero value of bEnable
  2233. // will enable the window. Based on empirical data, Win9x seems to
  2234. // look at only the low 16 bits of bEnable. This causes a problem,
  2235. // for example, if the caller passes a count of items with the intent
  2236. // to enable a window when the count is >0. That will fail when the
  2237. // count is a multiple of 64K, but will be nearly impossible to find
  2238. // and fix the problem. See Visual Studio 7 bug # 178556 for an
  2239. // example of such a bug.
  2240. return(EnableWindow(hWnd, (bEnable != 0)));
  2241. }
  2242. End=
  2243. [EFunc]
  2244. TemplateName=EndUpdateResourceW
  2245. Begin=
  2246. BOOL __stdcall GodotEndUpdateResourceW(HANDLE hUpdate, BOOL fDiscard)
  2247. {
  2248. // UNSUPPORTED FUNCTION: Documented as a failure stub
  2249. return(EndUpdateResourceInternalW(hUpdate, fDiscard));
  2250. }
  2251. End=
  2252. [EFunc]
  2253. TemplateName=EnumCalendarInfoW
  2254. Begin=
  2255. BOOL __stdcall
  2256. GodotEnumCalendarInfoW(CALINFO_ENUMPROCW lpCalInfoEnumProc, LCID Locale, CALID Calendar, CALTYPE CalType)
  2257. {
  2258. // Begin locals
  2259. BOOL RetVal = FALSE;
  2260. LPGODOTTLSINFO lpgti;
  2261. if(!(lpgti = GetThreadInfoSafe(TRUE)))
  2262. {
  2263. SetLastError(ERROR_OUTOFMEMORY);
  2264. return(FALSE);
  2265. }
  2266. if((lpgti->pfnCalendarInfo &&
  2267. (lpgti->pfnCalendarInfo != lpCalInfoEnumProc)) ||
  2268. lpgti->cCalendarInfo >= GODOTMAXREFCOUNT)
  2269. {
  2270. // A hook is already defined and it is a different hook. We
  2271. // must fail the call here.
  2272. SetLastError(ERROR_INVALID_FILTER_PROC);
  2273. return(FALSE);
  2274. }
  2275. lpgti->pfnCalendarInfo = lpCalInfoEnumProc;
  2276. lpgti->cCalendarInfo++;
  2277. RetVal=EnumCalendarInfoA(&EnumCalendarInfoProc, Locale, Calendar, CalType);
  2278. lpgti->pfnCalendarInfo = NULL;
  2279. lpgti->cCalendarInfo--;
  2280. return RetVal;
  2281. }
  2282. End=
  2283. [EFunc]
  2284. TemplateName=EnumCalendarInfoExW
  2285. Begin=
  2286. BOOL __stdcall
  2287. GodotEnumCalendarInfoExW(CALINFO_ENUMPROCEXW lpEnumProcEx, LCID Locale, CALID Calendar, CALTYPE CalType)
  2288. {
  2289. // Begin locals
  2290. BOOL RetVal = FALSE;
  2291. if (s_pfnEnumCalendarInfoExA == NULL)
  2292. {
  2293. // Must allocate stuff for this API call
  2294. s_pfnEnumCalendarInfoExA = (PFNeciea)GetKernelProc("EnumCalendarInfoExA");
  2295. }
  2296. if (s_pfnEnumCalendarInfoExA)
  2297. {
  2298. LPGODOTTLSINFO lpgti;
  2299. if(!(lpgti = GetThreadInfoSafe(TRUE)))
  2300. {
  2301. SetLastError(ERROR_OUTOFMEMORY);
  2302. return(FALSE);
  2303. }
  2304. if((lpgti->pfnCalendarInfoEx &&
  2305. (lpgti->pfnCalendarInfoEx != lpEnumProcEx)) ||
  2306. lpgti->cCalendarInfoEx >= GODOTMAXREFCOUNT)
  2307. {
  2308. // A hook is already defined and it is a different hook. We
  2309. // must fail the call here.
  2310. SetLastError(ERROR_INVALID_FILTER_PROC);
  2311. return(FALSE);
  2312. }
  2313. lpgti->pfnCalendarInfoEx = lpEnumProcEx;
  2314. lpgti->cCalendarInfoEx++;
  2315. RetVal = (s_pfnEnumCalendarInfoExA (&EnumCalendarInfoProcEx, Locale, Calendar, CalType ));
  2316. lpgti->pfnCalendarInfoEx = NULL;
  2317. lpgti->cCalendarInfoEx--;
  2318. }
  2319. else
  2320. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  2321. return RetVal;
  2322. }
  2323. End=
  2324. [EFunc]
  2325. TemplateName=EnumClipboardFormats
  2326. Begin=
  2327. UINT __stdcall
  2328. GodotEnumClipboardFormats(UINT uFormat)
  2329. {
  2330. UINT RetVal = EnumClipboardFormats(uFormat);
  2331. if((RetVal==0) && (GetLastError() == 0))
  2332. {
  2333. // The zero return with no error can mean one of three things to us:
  2334. // 1) uFormat is one of our faux formats that we told them is valid
  2335. // 2) uFormat is an entirely invalid format that is not really in anyone's chain
  2336. // 3) uFormat is the last legitimate member of the chain according to the system
  2337. BOOL fSystemLikes = IsClipboardFormatAvailable(uFormat);
  2338. BOOL fGodotLikes = GodotIsClipboardFormatAvailable(uFormat);
  2339. if(!fSystemLikes && fGodotLikes)
  2340. {
  2341. // This is case #1 above. Therefore, if this is CF_TEXT then
  2342. // we have one more to pass, otherwise we are done.
  2343. if(uFormat==CF_TEXT)
  2344. RetVal = CF_OEMTEXT;
  2345. }
  2346. else if(!fSystemLikes && !fGodotLikes)
  2347. {
  2348. // This is case #2 above, nothing to do here at all
  2349. }
  2350. else
  2351. {
  2352. // This is case #3 above: our hardest one to do. Basically, we have to
  2353. // add 0-2 formats to the chain:
  2354. // a) if system has CF_TEXT but not CF_UNICODETEXT, then we pass CF_UNICODETEXT
  2355. // b) if system has CF_UNICODETEXT but not CF_TEXT, then as pass CF_TEXT
  2356. // (CF_OEMTEXT will be passed next time via case #1 above)
  2357. // c) if system has neither, then we are done
  2358. if(IsClipboardFormatAvailable(CF_TEXT) && !IsClipboardFormatAvailable(CF_UNICODETEXT))
  2359. {
  2360. RetVal = CF_UNICODETEXT;
  2361. }
  2362. else if(IsClipboardFormatAvailable(CF_UNICODETEXT) && !IsClipboardFormatAvailable(CF_TEXT))
  2363. {
  2364. RetVal = CF_TEXT;
  2365. }
  2366. }
  2367. }
  2368. return(RetVal);
  2369. }
  2370. End=
  2371. [EFunc]
  2372. TemplateName=EnumDateFormatsW
  2373. Begin=
  2374. BOOL __stdcall
  2375. GodotEnumDateFormatsW(DATEFMT_ENUMPROCW lpDateFmtEnumProc, LCID Locale, DWORD dwFlags)
  2376. {
  2377. // Begin locals
  2378. BOOL RetVal = FALSE;
  2379. LPGODOTTLSINFO lpgti;
  2380. if(!(lpgti = GetThreadInfoSafe(TRUE)))
  2381. {
  2382. SetLastError(ERROR_OUTOFMEMORY);
  2383. return(FALSE);
  2384. }
  2385. if((lpgti->pfnDateFormats &&
  2386. (lpgti->pfnDateFormats != lpDateFmtEnumProc)) ||
  2387. lpgti->cDateFormats >= GODOTMAXREFCOUNT)
  2388. {
  2389. // A hook is already defined and it is a different hook. We
  2390. // must fail the call here.
  2391. SetLastError(ERROR_INVALID_FILTER_PROC);
  2392. return(FALSE);
  2393. }
  2394. lpgti->pfnDateFormats = lpDateFmtEnumProc;
  2395. lpgti->cDateFormats++;
  2396. RetVal=EnumDateFormatsA(&EnumDateFormatsProc, Locale, dwFlags);
  2397. lpgti->pfnDateFormats = NULL;
  2398. lpgti->cDateFormats--;
  2399. return RetVal;
  2400. }
  2401. End=
  2402. [EFunc]
  2403. TemplateName=EnumDateFormatsExW
  2404. Begin=
  2405. BOOL __stdcall
  2406. GodotEnumDateFormatsExW(DATEFMT_ENUMPROCEXW lpDateFmtEnumProcEx, LCID Locale, DWORD dwFlags)
  2407. {
  2408. // Begin locals
  2409. BOOL RetVal = FALSE;
  2410. if (s_pfnEnumDateFormatsExA == NULL)
  2411. {
  2412. // Must allocate stuff for this API call
  2413. s_pfnEnumDateFormatsExA = (PFNedfea)GetKernelProc("EnumDateFormatsExA");
  2414. }
  2415. if (s_pfnEnumDateFormatsExA)
  2416. {
  2417. LPGODOTTLSINFO lpgti;
  2418. if(!(lpgti = GetThreadInfoSafe(TRUE)))
  2419. {
  2420. SetLastError(ERROR_OUTOFMEMORY);
  2421. return(FALSE);
  2422. }
  2423. if((lpgti->pfnDateFormatsEx &&
  2424. (lpgti->pfnDateFormatsEx != lpDateFmtEnumProcEx)) ||
  2425. lpgti->cDateFormats >= GODOTMAXREFCOUNT)
  2426. {
  2427. // A hook is already defined and it is a different hook. We
  2428. // must fail the call here.
  2429. SetLastError(ERROR_INVALID_FILTER_PROC);
  2430. return(FALSE);
  2431. }
  2432. lpgti->pfnDateFormatsEx = lpDateFmtEnumProcEx;
  2433. lpgti->cDateFormats++;
  2434. RetVal = (s_pfnEnumDateFormatsExA (&EnumDateFormatsProcEx, Locale, dwFlags));
  2435. lpgti->pfnDateFormatsEx = NULL;
  2436. lpgti->cDateFormats--;
  2437. }
  2438. else
  2439. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  2440. return RetVal;
  2441. }
  2442. End=
  2443. [EFunc]
  2444. TemplateName=EnumDisplayDevicesW
  2445. Begin=
  2446. BOOL __stdcall
  2447. GodotEnumDisplayDevicesW(LPCWSTR lpDevice, DWORD iDevNum, PDISPLAY_DEVICEW pddw, DWORD dwFlags)
  2448. {
  2449. BOOL RetVal = FALSE;
  2450. if (!s_pfnEnumDisplayDevicesA)
  2451. // Must allocate stuff for this API call
  2452. s_pfnEnumDisplayDevicesA = (PFNedda)GetUserProc("EnumDisplayDevicesA");
  2453. if (s_pfnEnumDisplayDevicesA)
  2454. {
  2455. LPSTR lpDeviceAnsi;
  2456. DISPLAY_DEVICEA dda;
  2457. GODOT_TO_ACP_STACKALLOC(lpDevice, lpDeviceAnsi);
  2458. ZeroMemory(&dda, sizeof(DISPLAY_DEVICEA));
  2459. dda.cb = sizeof(DISPLAY_DEVICEA);
  2460. RetVal = (s_pfnEnumDisplayDevicesA(lpDeviceAnsi, iDevNum, &dda, dwFlags));
  2461. if(RetVal)
  2462. {
  2463. MultiByteToWideChar(g_acp, 0, dda.DeviceName, -1, pddw->DeviceName, 32);
  2464. MultiByteToWideChar(g_acp, 0, dda.DeviceString, -1, pddw->DeviceString, 128);
  2465. pddw->StateFlags = dda.StateFlags;
  2466. MultiByteToWideChar(g_acp, 0, dda.DeviceID, -1, pddw->DeviceID, 128);
  2467. MultiByteToWideChar(g_acp, 0, dda.DeviceKey, -1, pddw->DeviceKey, 128);
  2468. }
  2469. }
  2470. else
  2471. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  2472. return RetVal;
  2473. }
  2474. End=
  2475. [EFunc]
  2476. TemplateName=EnumDisplaySettingsW
  2477. Begin=
  2478. BOOL __stdcall
  2479. GodotEnumDisplaySettingsW(LPCWSTR lpszDeviceName, DWORD iModeNum, LPDEVMODEW lpDevMode)
  2480. {
  2481. // Begin locals
  2482. BOOL RetVal;
  2483. LPSTR lpszDeviceNameAnsi;
  2484. DEVMODEA dma;
  2485. // Begin precall
  2486. GODOT_TO_ACP_STACKALLOC(lpszDeviceName, lpszDeviceNameAnsi);
  2487. if(!lpszDeviceNameAnsi && lpszDeviceName)
  2488. return(FALSE);
  2489. RetVal=EnumDisplaySettingsA(lpszDeviceNameAnsi, iModeNum, &dma);
  2490. if(RetVal && lpDevMode)
  2491. {
  2492. // We assume that lpDevMode will have room for the extra bytes, if any
  2493. DevModeWfromA(lpDevMode, &dma);
  2494. }
  2495. // Finished
  2496. return RetVal;
  2497. }
  2498. End=
  2499. [EFunc]
  2500. TemplateName=EnumDisplaySettingsExW
  2501. Begin=
  2502. BOOL __stdcall
  2503. GodotEnumDisplaySettingsExW(LPCWSTR lpszDeviceName, DWORD iModeNum, LPDEVMODEW lpDevMode, DWORD dwFlags)
  2504. {
  2505. // Begin locals
  2506. BOOL RetVal = FALSE;
  2507. if (s_pfnEnumDisplaySettingsExA == NULL)
  2508. {
  2509. // Must allocate stuff for this API call
  2510. s_pfnEnumDisplaySettingsExA = (PFNedsea)GetUserProc("EnumDisplaySettingsExA");
  2511. }
  2512. if (s_pfnEnumDisplaySettingsExA)
  2513. {
  2514. LPSTR lpszDeviceNameAnsi;
  2515. DEVMODEA dma;
  2516. GODOT_TO_ACP_STACKALLOC(lpszDeviceName, lpszDeviceNameAnsi);
  2517. if(!lpszDeviceNameAnsi && lpszDeviceName)
  2518. return(FALSE);
  2519. ZeroMemory(&dma, sizeof(DEVMODEA));
  2520. dma.dmSize = sizeof(DEVMODEA);
  2521. RetVal = (s_pfnEnumDisplaySettingsExA(lpszDeviceNameAnsi, iModeNum, &dma, dwFlags));
  2522. if(RetVal && lpDevMode)
  2523. {
  2524. // We assume that lpDevMode will have room for the extra bytes, if any
  2525. DevModeWfromA(lpDevMode, &dma);
  2526. }
  2527. }
  2528. else
  2529. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  2530. // Finished
  2531. return RetVal;
  2532. }
  2533. End=
  2534. [EFunc]
  2535. TemplateName=EnumerateSecurityPackagesW
  2536. Begin=
  2537. SECURITY_STATUS __stdcall
  2538. GodotEnumerateSecurityPackagesW(unsigned long int * pcPackages, PSecPkgInfoW * ppPackageInfo)
  2539. {
  2540. // ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
  2541. return(SEC_E_UNSUPPORTED_FUNCTION);
  2542. }
  2543. End=
  2544. [EFunc]
  2545. TemplateName=EnumFontFamiliesW
  2546. Begin=
  2547. int __stdcall
  2548. GodotEnumFontFamiliesW(HDC hdc, LPCWSTR lpszFamily, FONTENUMPROCW lpEnumFontFamProc, LPARAM lParam)
  2549. {
  2550. // Begin locals
  2551. int RetVal;
  2552. LPSTR lpszFamilyAnsi;
  2553. LPGODOTTLSINFO lpgti;
  2554. if(!(lpgti = GetThreadInfoSafe(TRUE)))
  2555. {
  2556. SetLastError(ERROR_OUTOFMEMORY);
  2557. return(0);
  2558. }
  2559. if((lpgti->pfnFontFamilies &&
  2560. (lpgti->pfnFontFamilies != lpEnumFontFamProc)) ||
  2561. lpgti->cFontFamilies >= GODOTMAXREFCOUNT)
  2562. {
  2563. // A hook is already defined and it is a different hook. We
  2564. // must fail the call here.
  2565. SetLastError(ERROR_INVALID_FILTER_PROC);
  2566. return(0);
  2567. }
  2568. lpgti->pfnFontFamilies = lpEnumFontFamProc;
  2569. lpgti->cFontFamilies++;
  2570. GODOT_TO_ACP_STACKALLOC(lpszFamily, lpszFamilyAnsi);
  2571. RetVal=EnumFontFamiliesA(hdc, lpszFamilyAnsi, (FONTENUMPROCA)&EnumFontFamProc, lParam);
  2572. lpgti->pfnFontFamilies = NULL;
  2573. lpgti->cFontFamilies--;
  2574. return RetVal;
  2575. }
  2576. End=
  2577. [EFunc]
  2578. TemplateName=EnumFontFamiliesExW
  2579. Begin=
  2580. int __stdcall
  2581. GodotEnumFontFamiliesExW( HDC hdc,
  2582. LPLOGFONTW lpLogfont,
  2583. FONTENUMPROCW lpEnumFontFamExProc,
  2584. LPARAM lParam,
  2585. DWORD dwFlags
  2586. )
  2587. {
  2588. // Begin locals
  2589. int RetVal;
  2590. LOGFONTA lfa;
  2591. LPGODOTTLSINFO lpgti;
  2592. if(!(lpgti = GetThreadInfoSafe(TRUE)))
  2593. {
  2594. SetLastError(ERROR_OUTOFMEMORY);
  2595. return(0);
  2596. }
  2597. if((lpgti->pfnFontFamiliesEx &&
  2598. (lpgti->pfnFontFamiliesEx != lpEnumFontFamExProc)) ||
  2599. lpgti->cFontFamiliesEx >= GODOTMAXREFCOUNT)
  2600. {
  2601. // A hook is already defined and it is a different hook. We
  2602. // must fail the call here.
  2603. SetLastError(ERROR_INVALID_FILTER_PROC);
  2604. return(0);
  2605. }
  2606. lpgti->pfnFontFamiliesEx = lpEnumFontFamExProc;
  2607. lpgti->cFontFamiliesEx++;
  2608. ZeroMemory(&lfa, sizeof(LOGFONTA));
  2609. LogFontAfromW(&lfa, lpLogfont);
  2610. RetVal=EnumFontFamiliesExA(hdc, &lfa, (FONTENUMPROCA)&EnumFontFamExProc, lParam, dwFlags);
  2611. lpgti->pfnFontFamiliesEx = NULL;
  2612. lpgti->cFontFamiliesEx--;
  2613. return RetVal;
  2614. }
  2615. End=
  2616. [EFunc]
  2617. TemplateName=EnumFontsW
  2618. Begin=
  2619. int __stdcall
  2620. GodotEnumFontsW(HDC hdc, LPCWSTR lpFaceName, FONTENUMPROCW lpFontFunc, LPARAM lParam)
  2621. {
  2622. // Begin locals
  2623. int RetVal;
  2624. LPSTR lpFaceNameAnsi;
  2625. LPGODOTTLSINFO lpgti;
  2626. if(!(lpgti = GetThreadInfoSafe(TRUE)))
  2627. {
  2628. SetLastError(ERROR_OUTOFMEMORY);
  2629. return(0);
  2630. }
  2631. if((lpgti->pfnFonts &&
  2632. (lpgti->pfnFonts != lpFontFunc)) ||
  2633. lpgti->cFonts >= GODOTMAXREFCOUNT)
  2634. {
  2635. // A hook is already defined and it is a different hook. We
  2636. // must fail the call here.
  2637. SetLastError(ERROR_INVALID_FILTER_PROC);
  2638. return(0);
  2639. }
  2640. lpgti->pfnFonts = lpFontFunc;
  2641. lpgti->cFonts++;
  2642. GODOT_TO_ACP_STACKALLOC(lpFaceName, lpFaceNameAnsi);
  2643. RetVal=EnumFontsA(hdc, lpFaceNameAnsi, &EnumFontsProc, lParam);
  2644. lpgti->pfnFonts = NULL;
  2645. lpgti->cFonts--;
  2646. return RetVal;
  2647. }
  2648. End=
  2649. [EFunc]
  2650. TemplateName=EnumICMProfilesW
  2651. Begin=
  2652. int __stdcall
  2653. GodotEnumICMProfilesW(HDC hDC, ICMENUMPROCW lpEnumICMProfilesFunc, LPARAM lParam)
  2654. {
  2655. // Begin locals
  2656. int RetVal;
  2657. LPGODOTTLSINFO lpgti;
  2658. if(!(lpgti = GetThreadInfoSafe(TRUE)))
  2659. {
  2660. SetLastError(ERROR_OUTOFMEMORY);
  2661. return(0);
  2662. }
  2663. if((lpgti->pfnICMProfiles &&
  2664. (lpgti->pfnICMProfiles != lpEnumICMProfilesFunc)) ||
  2665. lpgti->cICMProfiles >= GODOTMAXREFCOUNT)
  2666. {
  2667. // A hook is already defined and it is a different hook. We
  2668. // must fail the call here.
  2669. SetLastError(ERROR_INVALID_FILTER_PROC);
  2670. return(0);
  2671. }
  2672. lpgti->pfnICMProfiles = lpEnumICMProfilesFunc;
  2673. lpgti->cICMProfiles++;
  2674. RetVal=EnumICMProfilesA(hDC, &EnumICMProfilesProcCallback, lParam);
  2675. lpgti->pfnICMProfiles = NULL;
  2676. lpgti->cICMProfiles--;
  2677. return RetVal;
  2678. }
  2679. End=
  2680. [EFunc]
  2681. TemplateName=EnumMonitorsW
  2682. Begin=
  2683. BOOL __stdcall
  2684. GodotEnumMonitorsW(LPWSTR _noname0, DWORD _noname1, LPBYTE _noname2, DWORD _noname3,
  2685. LPDWORD _noname4, LPDWORD _noname5)
  2686. {
  2687. // ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
  2688. return(EnumMonitorsW(_noname0, _noname1, _noname2, _noname3, _noname4, _noname5));
  2689. }
  2690. End=
  2691. [EFunc]
  2692. TemplateName=EnumPortsW
  2693. Begin=
  2694. BOOL __stdcall
  2695. GodotEnumPortsW(LPWSTR _noname0, DWORD _noname1, LPBYTE _noname2, DWORD _noname3,
  2696. LPDWORD _noname4, LPDWORD _noname5)
  2697. {
  2698. // ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
  2699. return(EnumPortsW(_noname0, _noname1, _noname2, _noname3, _noname4, _noname5));
  2700. }
  2701. End=
  2702. [EFunc]
  2703. TemplateName=EnumPrinterDriversW
  2704. Begin=
  2705. BOOL __stdcall
  2706. GodotEnumPrinterDriversW(LPWSTR _noname0, LPWSTR _noname1, DWORD _noname2, LPBYTE _noname3,
  2707. DWORD _noname4, LPDWORD _noname5, LPDWORD _noname6)
  2708. {
  2709. // ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
  2710. return(EnumPrinterDriversW(_noname0, _noname1, _noname2, _noname3, _noname4, _noname5, _noname6));
  2711. }
  2712. End=
  2713. [EFunc]
  2714. TemplateName=EnumPrintersW
  2715. Begin=
  2716. BOOL __stdcall
  2717. GodotEnumPrintersW(DWORD _noname0, LPWSTR _noname1, DWORD _noname2, LPBYTE _noname3,
  2718. DWORD _noname4, LPDWORD _noname5, LPDWORD _noname6)
  2719. {
  2720. // ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
  2721. return(EnumPrintersW(_noname0, _noname1, _noname2, _noname3, _noname4, _noname5, _noname6));
  2722. }
  2723. End=
  2724. [EFunc]
  2725. TemplateName=EnumPrintProcessorDatatypesW
  2726. Begin=
  2727. BOOL __stdcall
  2728. GodotEnumPrintProcessorDatatypesW(LPWSTR _noname0, LPWSTR _noname1, DWORD _noname2, LPBYTE _noname3,
  2729. DWORD _noname4, LPDWORD _noname5, LPDWORD _noname6)
  2730. {
  2731. // ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
  2732. return(EnumPrintProcessorDatatypesW(_noname0, _noname1, _noname2, _noname3,
  2733. _noname4, _noname5, _noname6));
  2734. }
  2735. End=
  2736. [EFunc]
  2737. TemplateName=EnumPrintProcessorsW
  2738. Begin=
  2739. BOOL __stdcall
  2740. GodotEnumPrintProcessorsW(LPWSTR pName, LPWSTR pEnvironment,
  2741. DWORD Level, LPBYTE pPrintProcessorInfo,
  2742. DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
  2743. {
  2744. // UNSUPPORTED FUNCTION: Documented as a failure stub
  2745. LPSTR pNameA, pEnvironmentA;
  2746. BOOL RetVal;
  2747. DWORD cbNeeded = 0;
  2748. DWORD cReturned = 0;
  2749. GODOT_TO_ACP_STACKALLOC(pName, pNameA);
  2750. GODOT_TO_ACP_STACKALLOC(pEnvironment, pEnvironmentA);
  2751. if((!pNameA && pName) ||
  2752. (!pEnvironmentA && pEnvironment))
  2753. {
  2754. SetLastError(ERROR_STACK_OVERFLOW);
  2755. return(FALSE);
  2756. }
  2757. if(pPrintProcessorInfo==NULL || cbBuf==0)
  2758. {
  2759. RetVal = EnumPrintProcessorsA(pNameA, pEnvironmentA, Level, NULL, 0, &cbNeeded, &cReturned);
  2760. // Note that the size we return is potentially twice as
  2761. // big as it needs to be on DBCS platforms. Unfortunate,
  2762. // but there is not much else we can do.
  2763. if(RetVal==FALSE && GetLastError()== ERROR_INSUFFICIENT_BUFFER && pcbNeeded)
  2764. *pcbNeeded = cbNeeded * sizeof(WCHAR);
  2765. if(pcReturned)
  2766. *pcReturned = cReturned;
  2767. }
  2768. else
  2769. {
  2770. LPBYTE pPrintProcessorInfoA;
  2771. DWORD cbBufA = (FDBCS_CPG(g_acp ? cbBuf : cbBuf / 2));
  2772. _STACKALLOC(cbBufA, pPrintProcessorInfoA);
  2773. if(pPrintProcessorInfoA==NULL)
  2774. {
  2775. return(FALSE);
  2776. }
  2777. RetVal = EnumPrintProcessorsA(pNameA, pEnvironmentA, Level, pPrintProcessorInfoA, cbBufA,
  2778. &cbNeeded, &cReturned);
  2779. if(RetVal==FALSE && GetLastError()== ERROR_INSUFFICIENT_BUFFER && pcbNeeded)
  2780. *pcbNeeded = cbNeeded * sizeof(WCHAR);
  2781. else if(RetVal)
  2782. {
  2783. PPRINTPROCESSOR_INFO_1W pPPIW = (PPRINTPROCESSOR_INFO_1W)pPrintProcessorInfo;
  2784. PPRINTPROCESSOR_INFO_1A pPPIA = (PPRINTPROCESSOR_INFO_1A)pPrintProcessorInfoA;
  2785. DWORD dwOffsetStr = (sizeof(PRINTPROCESSOR_INFO_1A) * cReturned);
  2786. DWORD ippi;
  2787. int cch = 0;
  2788. cbBufA -= dwOffsetStr;
  2789. for(ippi = 0; ippi < cReturned ; ippi++)
  2790. {
  2791. LPWSTR lpwz = (LPWSTR)pPrintProcessorInfo + dwOffsetStr;
  2792. cch = MultiByteToWideChar(g_acp, 0, pPPIA[ippi].pName, -1, lpwz, cbBufA/sizeof(WCHAR));
  2793. pPPIW[ippi].pName = lpwz;
  2794. dwOffsetStr += cch;
  2795. cbBufA -= cch;
  2796. }
  2797. if(pcbNeeded)
  2798. *pcbNeeded = dwOffsetStr + cch - (DWORD)pPrintProcessorInfo;
  2799. }
  2800. if(pcReturned)
  2801. *pcReturned = cReturned;
  2802. }
  2803. return(RetVal);
  2804. }
  2805. End=
  2806. [EFunc]
  2807. TemplateName=EnumPropsA
  2808. Begin=
  2809. int __stdcall
  2810. GodotEnumPropsA(HWND hWnd, PROPENUMPROCA lpEnumFunc)
  2811. {
  2812. // Begin locals
  2813. int RetVal = 0;
  2814. LPGODOTTLSINFO lpgti;
  2815. if(!(lpgti = GetThreadInfoSafe(TRUE)))
  2816. {
  2817. SetLastError(ERROR_OUTOFMEMORY);
  2818. return(0);
  2819. }
  2820. if((lpgti->pfnPropA &&
  2821. (lpgti->pfnPropA != lpEnumFunc)) ||
  2822. lpgti->cPropA >= GODOTMAXREFCOUNT)
  2823. {
  2824. // A hook is already defined and it is a different hook. We
  2825. // must fail the call here.
  2826. SetLastError(ERROR_INVALID_FILTER_PROC);
  2827. return(0);
  2828. }
  2829. lpgti->pfnPropA = lpEnumFunc;
  2830. lpgti->cPropA++;
  2831. RetVal=EnumPropsA(hWnd, &PropEnumProcA);
  2832. lpgti->pfnPropA = NULL;
  2833. lpgti->cPropA--;
  2834. return RetVal;
  2835. }
  2836. End=
  2837. [EFunc]
  2838. TemplateName=EnumPropsW
  2839. Begin=
  2840. int __stdcall
  2841. GodotEnumPropsW(HWND hWnd, PROPENUMPROCW lpEnumFunc)
  2842. {
  2843. // Begin locals
  2844. int RetVal = 0;
  2845. LPGODOTTLSINFO lpgti;
  2846. if(!(lpgti = GetThreadInfoSafe(TRUE)))
  2847. {
  2848. SetLastError(ERROR_OUTOFMEMORY);
  2849. return(0);
  2850. }
  2851. if((lpgti->pfnProp &&
  2852. (lpgti->pfnProp != lpEnumFunc)) ||
  2853. lpgti->cProp >= GODOTMAXREFCOUNT)
  2854. {
  2855. // A hook is already defined and it is a different hook. We
  2856. // must fail the call here.
  2857. SetLastError(ERROR_INVALID_FILTER_PROC);
  2858. return(0);
  2859. }
  2860. lpgti->pfnProp = lpEnumFunc;
  2861. lpgti->cProp++;
  2862. RetVal=EnumPropsA(hWnd, &PropEnumProc);
  2863. lpgti->pfnProp = NULL;
  2864. lpgti->cProp--;
  2865. return RetVal;
  2866. }
  2867. End=
  2868. [EFunc]
  2869. TemplateName=EnumPropsExA
  2870. Begin=
  2871. int __stdcall
  2872. GodotEnumPropsExA(HWND hWnd, PROPENUMPROCEXA lpEnumFunc, LPARAM lParam)
  2873. {
  2874. // Begin locals
  2875. int RetVal;
  2876. LPGODOTTLSINFO lpgti;
  2877. if(!(lpgti = GetThreadInfoSafe(TRUE)))
  2878. {
  2879. SetLastError(ERROR_OUTOFMEMORY);
  2880. return(0);
  2881. }
  2882. if((lpgti->pfnPropExA &&
  2883. (lpgti->pfnPropExA != lpEnumFunc)) ||
  2884. lpgti->cPropExA >= GODOTMAXREFCOUNT)
  2885. {
  2886. // A hook is already defined and it is a different hook. We
  2887. // must fail the call here.
  2888. SetLastError(ERROR_INVALID_FILTER_PROC);
  2889. return(0);
  2890. }
  2891. lpgti->pfnPropExA = lpEnumFunc;
  2892. lpgti->cPropExA++;
  2893. RetVal=EnumPropsExA(hWnd, &PropEnumProcExA, lParam);
  2894. lpgti->pfnPropExA = NULL;
  2895. lpgti->cPropExA--;
  2896. return RetVal;
  2897. }
  2898. End=
  2899. [EFunc]
  2900. TemplateName=EnumPropsExW
  2901. Begin=
  2902. int __stdcall
  2903. GodotEnumPropsExW(HWND hWnd, PROPENUMPROCEXW lpEnumFunc, LPARAM lParam)
  2904. {
  2905. // Begin locals
  2906. int RetVal;
  2907. LPGODOTTLSINFO lpgti;
  2908. if(!(lpgti = GetThreadInfoSafe(TRUE)))
  2909. {
  2910. SetLastError(ERROR_OUTOFMEMORY);
  2911. return(0);
  2912. }
  2913. if((lpgti->pfnPropEx &&
  2914. (lpgti->pfnPropEx != lpEnumFunc)) ||
  2915. lpgti->cPropEx >= GODOTMAXREFCOUNT)
  2916. {
  2917. // A hook is already defined and it is a different hook. We
  2918. // must fail the call here.
  2919. SetLastError(ERROR_INVALID_FILTER_PROC);
  2920. return(0);
  2921. }
  2922. lpgti->pfnPropEx = lpEnumFunc;
  2923. lpgti->cPropEx++;
  2924. RetVal=EnumPropsExA(hWnd, &PropEnumProcEx, lParam);
  2925. lpgti->pfnPropEx = NULL;
  2926. lpgti->cPropEx--;
  2927. return RetVal;
  2928. }
  2929. End=
  2930. [EFunc]
  2931. TemplateName=EnumSystemCodePagesW
  2932. Begin=
  2933. #define NLS_CODEPAGE_KEY "SYSTEM\\CurrentControlSet\\Control\\nls\\codepage"
  2934. #define MAX_KEYVALUEFULLINFO 256 /* max string length for key value full info */
  2935. #define ENUM_MAX_CP_SIZE 6 /* max size for cp id in registry */
  2936. BOOL __stdcall
  2937. GodotEnumSystemCodePagesW(CODEPAGE_ENUMPROCW lpCodePageEnumProc, DWORD dwFlags)
  2938. {
  2939. // Begin locals
  2940. BOOL fInstalled;
  2941. BOOL fCallEnumProc;
  2942. HKEY hKey;
  2943. LPSTR lpszValue;
  2944. LPSTR lpszData;
  2945. WCHAR wzValueString[MAX_KEYVALUEFULLINFO];
  2946. BYTE pStatic1[MAX_KEYVALUEFULLINFO];
  2947. BYTE pStatic2[MAX_KEYVALUEFULLINFO];
  2948. ULONG cbValue; /* size of value */
  2949. ULONG cbData; /* # bytes written Data */
  2950. DWORD dwIndex = 0;
  2951. DWORD dwType;
  2952. LONG rc;
  2953. BOOL fCancel = FALSE;
  2954. // Invalid Parameter Check:
  2955. // (function pointer is null)
  2956. if (lpCodePageEnumProc == NULL)
  2957. {
  2958. SetLastError( ERROR_INVALID_PARAMETER );
  2959. return ( FALSE );
  2960. }
  2961. // Invalid Flags Check:
  2962. // - flags other than valid ones
  2963. // - more than one of either supported or installed
  2964. if ( (dwFlags != CP_INSTALLED) &&
  2965. (dwFlags != CP_SUPPORTED) )
  2966. {
  2967. SetLastError(ERROR_INVALID_FLAGS);
  2968. return (FALSE);
  2969. }
  2970. // Initialize flag option.
  2971. fInstalled = dwFlags & CP_INSTALLED;
  2972. // Loop through the code page ids in the registry, call the function
  2973. // pointer for each one that meets the flag criteria.
  2974. // End loop if either FALSE is returned from the callback function
  2975. // or the end of the list is reached.
  2976. // Always need to ignore the ACP, OEMCP, MACCP, and OEMHAL entries.
  2977. if (ERROR_SUCCESS != RegOpenKeyExA(HKEY_LOCAL_MACHINE, NLS_CODEPAGE_KEY, 0, KEY_QUERY_VALUE, &hKey) )
  2978. {
  2979. SetLastError(ERROR_BADDB);
  2980. return (FALSE);
  2981. }
  2982. // Initialize some buffers
  2983. ZeroMemory(pStatic1, MAX_KEYVALUEFULLINFO);
  2984. ZeroMemory(pStatic2, MAX_KEYVALUEFULLINFO);
  2985. lpszValue = (LPSTR)pStatic1;
  2986. lpszData = (LPSTR)pStatic2;
  2987. cbValue = MAX_KEYVALUEFULLINFO;
  2988. cbData = MAX_KEYVALUEFULLINFO;
  2989. // Call the first time
  2990. rc = RegEnumValueA(hKey, dwIndex, lpszValue, &cbValue, NULL, &dwType, (LPBYTE)lpszData, &cbData);
  2991. while (rc != ERROR_NO_MORE_ITEMS)
  2992. {
  2993. fCallEnumProc = TRUE;
  2994. if (rc != ERROR_SUCCESS)
  2995. {
  2996. // If we get a different error, then the registry
  2997. // is corrupt. Just return FALSE.
  2998. SetLastError(ERROR_BADDB);
  2999. RegCloseKey(hKey);
  3000. return (FALSE);
  3001. }
  3002. // Check character size of the system CodePage value
  3003. if ( (cbValue >= ENUM_MAX_CP_SIZE) ||
  3004. ((*lpszValue < '0') || (*lpszValue > '9')) )
  3005. fCallEnumProc = FALSE;
  3006. // Check flag to call the callback function and size of CodePage value.
  3007. if (fCallEnumProc)
  3008. {
  3009. if ( !fInstalled || (fInstalled && (*lpszData)) )
  3010. {
  3011. // Convert the string to Unicode
  3012. ZeroMemory(wzValueString, MAX_KEYVALUEFULLINFO * sizeof(WCHAR));
  3013. MultiByteToWideChar(g_acp, 0, lpszValue, -1, wzValueString, MAX_KEYVALUEFULLINFO - 1);
  3014. // Call the callback function.
  3015. if (((*lpCodePageEnumProc)(wzValueString)) != TRUE)
  3016. {
  3017. fCancel = TRUE;
  3018. break;
  3019. }
  3020. }
  3021. }
  3022. // Increment enumeration index value and get the next enumeration.
  3023. // Initialize buffer of system locale value & data variables
  3024. dwIndex++;
  3025. ZeroMemory(pStatic1, MAX_KEYVALUEFULLINFO);
  3026. ZeroMemory(pStatic2, MAX_KEYVALUEFULLINFO);
  3027. lpszValue = (LPSTR)pStatic1;
  3028. lpszData = (LPSTR)pStatic2;
  3029. cbValue = MAX_KEYVALUEFULLINFO;
  3030. cbData = MAX_KEYVALUEFULLINFO;
  3031. rc = RegEnumValueA(hKey, dwIndex, lpszValue, &cbValue, NULL, &dwType, (LPBYTE)lpszData, &cbData);
  3032. }
  3033. // If they have not cancelled yet, tack on custom ones
  3034. if(!fCancel)
  3035. {
  3036. // UTF-7
  3037. if ((* lpCodePageEnumProc)(L"65000"))
  3038. {
  3039. // UTF-8
  3040. if ((* lpCodePageEnumProc)(L"65001"))
  3041. {
  3042. // GB 18030: we test the "installed" bit by whether or not
  3043. // we can get a handle to the DLL via our LoadLibrary call.
  3044. if(!fInstalled || (fInstalled && GetGB18030Handle()))
  3045. (* lpCodePageEnumProc)(L"54936");
  3046. }
  3047. }
  3048. }
  3049. // Returns success if we made it this far, even if they cancelled
  3050. RegCloseKey(hKey);
  3051. return(TRUE);
  3052. }
  3053. End=
  3054. [EFunc]
  3055. TemplateName=EnumSystemLocalesW
  3056. Begin=
  3057. BOOL __stdcall
  3058. GodotEnumSystemLocalesW(LOCALE_ENUMPROCW lpLocaleEnumProc, DWORD dwFlags)
  3059. {
  3060. // Begin locals
  3061. BOOL RetVal;
  3062. LPGODOTTLSINFO lpgti;
  3063. if(!(lpgti = GetThreadInfoSafe(TRUE)))
  3064. {
  3065. SetLastError(ERROR_OUTOFMEMORY);
  3066. return(FALSE);
  3067. }
  3068. if((lpgti->pfnLocales &&
  3069. (lpgti->pfnLocales != lpLocaleEnumProc)) ||
  3070. lpgti->cLocales >= GODOTMAXREFCOUNT)
  3071. {
  3072. // A hook is already defined and it is a different hook. We
  3073. // must fail the call here.
  3074. SetLastError(ERROR_INVALID_FILTER_PROC);
  3075. return(FALSE);
  3076. }
  3077. lpgti->pfnLocales = lpLocaleEnumProc;
  3078. RetVal=EnumSystemLocalesA(&EnumLocalesProc, dwFlags);
  3079. lpgti->pfnLocales = NULL;
  3080. return RetVal;
  3081. }
  3082. End=
  3083. [EFunc]
  3084. TemplateName=EnumTimeFormatsW
  3085. Begin=
  3086. BOOL __stdcall
  3087. GodotEnumTimeFormatsW(TIMEFMT_ENUMPROCW lpTimeFmtEnumProc, LCID Locale, DWORD dwFlags)
  3088. {
  3089. // Begin locals
  3090. BOOL RetVal;
  3091. LPGODOTTLSINFO lpgti;
  3092. if(!(lpgti = GetThreadInfoSafe(TRUE)))
  3093. {
  3094. SetLastError(ERROR_OUTOFMEMORY);
  3095. return(FALSE);
  3096. }
  3097. if((lpgti->pfnTimeFormats &&
  3098. (lpgti->pfnTimeFormats != lpTimeFmtEnumProc)) ||
  3099. lpgti->cTimeFormats >= GODOTMAXREFCOUNT)
  3100. {
  3101. // A hook is already defined and it is a different hook. We
  3102. // must fail the call here.
  3103. SetLastError(ERROR_INVALID_FILTER_PROC);
  3104. return(FALSE);
  3105. }
  3106. lpgti->pfnTimeFormats = lpTimeFmtEnumProc;
  3107. lpgti->cTimeFormats++;
  3108. RetVal=EnumTimeFormatsA(&EnumTimeFormatsProc, Locale, dwFlags);
  3109. lpgti->pfnTimeFormats = NULL;
  3110. lpgti->cTimeFormats--;
  3111. return RetVal;
  3112. }
  3113. End=
  3114. [EFunc]
  3115. TemplateName=ExpandEnvironmentStringsW
  3116. Begin=
  3117. DWORD __stdcall
  3118. GodotExpandEnvironmentStringsW(LPCWSTR lpSrc, LPWSTR lpDst, DWORD nSize)
  3119. {
  3120. // Begin locals
  3121. DWORD RetVal;
  3122. LPSTR lpSrcAnsi;
  3123. LPSTR lpDstAnsi;
  3124. _STACKALLOC((nSize*g_mcs)+1, lpDstAnsi);
  3125. GODOT_TO_ACP_STACKALLOC(lpSrc, lpSrcAnsi);
  3126. if((!lpSrcAnsi && lpSrc) ||
  3127. (!lpDstAnsi))
  3128. {
  3129. return(0);
  3130. }
  3131. ZeroMemory(lpDstAnsi, (nSize*g_mcs)+1);
  3132. RetVal=ExpandEnvironmentStringsA(lpSrcAnsi, lpDstAnsi, nSize);
  3133. if(RetVal <= nSize)
  3134. {
  3135. // Only convert if the call succeeded; RetVal will
  3136. // always contain the size whether the function
  3137. // succeeded or not
  3138. MultiByteToWideChar(g_acp, 0, lpDstAnsi, -1, lpDst, RetVal);
  3139. }
  3140. // Finished
  3141. return RetVal;
  3142. }
  3143. End=
  3144. [EFunc]
  3145. TemplateName=ExtractIconW
  3146. Begin=
  3147. HICON __stdcall
  3148. GodotExtractIconW( HINSTANCE hInst,
  3149. LPCWSTR lpszExeFileName,
  3150. UINT nIconIndex
  3151. )
  3152. {
  3153. LPSTR lpszExeFileNameAnsi;
  3154. GODOT_TO_ACP_STACKALLOC(lpszExeFileName, lpszExeFileNameAnsi);
  3155. return(ExtractIconA(hInst, lpszExeFileNameAnsi, nIconIndex));
  3156. }
  3157. End=
  3158. [EFunc]
  3159. TemplateName=ExtractIconExW
  3160. Begin=
  3161. UINT __stdcall
  3162. GodotExtractIconExW(LPCWSTR lpszFile, int nIconIndex, HICON * phiconLarge, HICON * phiconSmall, UINT nIcons)
  3163. {
  3164. LPSTR lpszFileAnsi;
  3165. GODOT_TO_ACP_STACKALLOC(lpszFile, lpszFileAnsi);
  3166. return(ExtractIconExA(lpszFileAnsi, nIconIndex, phiconLarge, phiconSmall, nIcons));
  3167. }
  3168. End=
  3169. [EFunc]
  3170. TemplateName=ExtTextOutW
  3171. Begin=
  3172. BOOL __stdcall
  3173. GodotExtTextOutW(HDC hdc, int X, int Y, UINT eto, const LPRECT lprc,
  3174. LPCWSTR lpString, UINT cbCount, const PINT lpDx)
  3175. {
  3176. // Obtained all logic here from Office's MsoExtTextOutW function. :-)
  3177. if ((!lpString) || (cbCount == 0))
  3178. {
  3179. char chT;
  3180. return ExtTextOutA(hdc, X, Y, eto, lprc, &chT, cbCount, lpDx);
  3181. }
  3182. // Optimize for all < 128 case
  3183. // CONSIDER: This code could likely be faster, couldn't it???
  3184. if (!(eto & ETO_GLYPH_INDEX) && cbCount < 256 && lpString[0] <= 127)
  3185. {
  3186. char lpchA[256];
  3187. register UINT ich;
  3188. BOOL fAscii = TRUE;
  3189. // Optimize for the pure ASCII case
  3190. for (ich = 0; ich < cbCount; ich++)
  3191. {
  3192. WCHAR wch = lpString[ich];
  3193. if ( wch <= 127 )
  3194. lpchA[ich] = (char) wch;
  3195. else
  3196. {
  3197. fAscii = FALSE;
  3198. break;
  3199. }
  3200. }
  3201. if (fAscii)
  3202. return ExtTextOutA(hdc, X, Y, eto, lprc, lpchA, cbCount, lpDx);
  3203. }
  3204. // Call the 'W' version of the API, its safe now!
  3205. return ExtTextOutW(hdc, X, Y, eto, lprc, lpString, cbCount, lpDx);
  3206. }
  3207. End=
  3208. [EFunc]
  3209. TemplateName=FillConsoleOutputCharacterW
  3210. Begin=
  3211. BOOL __stdcall
  3212. GodotFillConsoleOutputCharacterW( HANDLE hConsoleOutput,
  3213. WCHAR cCharacter,
  3214. DWORD nLength,
  3215. COORD dwWriteCoord,
  3216. LPDWORD lpNumberOfCharsWritten
  3217. )
  3218. {
  3219. // Begin locals
  3220. char * cCharacterAnsi[2];
  3221. WideCharToMultiByte(g_oemcp, 0, (LPWSTR)&cCharacter, 1, (LPSTR)&cCharacterAnsi, 2, NULL, NULL);
  3222. // Call the 'A' version of the API
  3223. return(FillConsoleOutputCharacterA(hConsoleOutput,
  3224. *cCharacterAnsi[0],
  3225. nLength,
  3226. dwWriteCoord,
  3227. lpNumberOfCharsWritten
  3228. ));
  3229. }
  3230. End=
  3231. [EFunc]
  3232. TemplateName=FindExecutableW
  3233. Begin=
  3234. HINSTANCE __stdcall
  3235. GodotFindExecutableW(LPCWSTR lpFile, LPCWSTR lpDirectory, LPWSTR lpResult)
  3236. {
  3237. // UNSUPPORTED FUNCTION: Documented as a failure stub
  3238. char lpResultAnsi[MAX_PATH + 1];
  3239. LPSTR lpFileAnsi, lpDirectoryAnsi;
  3240. HINSTANCE RetVal;
  3241. GODOT_TO_ACP_STACKALLOC(lpFile, lpFileAnsi);
  3242. GODOT_TO_ACP_STACKALLOC(lpDirectory, lpDirectoryAnsi);
  3243. if((!lpFileAnsi && lpFile) ||
  3244. (!lpDirectoryAnsi && lpDirectory))
  3245. {
  3246. return(0);
  3247. }
  3248. RetVal = FindExecutableA(lpFileAnsi, lpDirectoryAnsi, lpResultAnsi);
  3249. if(lpResult)
  3250. {
  3251. if(RetVal)
  3252. MultiByteToWideChar(g_acp, 0, lpResultAnsi, -1, lpResult, MAX_PATH);
  3253. else
  3254. *lpResult = L'\0';
  3255. }
  3256. return(RetVal);
  3257. }
  3258. End=
  3259. [EFunc]
  3260. TemplateName=FindFirstChangeNotificationW
  3261. Begin=
  3262. HANDLE __stdcall
  3263. GodotFindFirstChangeNotificationW(LPCWSTR lpPathName, BOOL bWatchSubtree, DWORD dwNotifyFilter)
  3264. {
  3265. // Begin locals
  3266. LPSTR lpPathNameAnsi;
  3267. // Begin precall
  3268. GODOT_TO_CPG_STACKALLOC(lpPathName, lpPathNameAnsi, FILES_CPG, g_mcs);
  3269. if(lpPathNameAnsi==NULL)
  3270. {
  3271. return(INVALID_HANDLE_VALUE);
  3272. }
  3273. return(FindFirstChangeNotificationA(lpPathNameAnsi, bWatchSubtree, dwNotifyFilter));
  3274. }
  3275. End=
  3276. [EFunc]
  3277. TemplateName=FindFirstFileW
  3278. Begin=
  3279. // We need an alternate "default" char when looking for file names, because the
  3280. // usual "?" is a valid wildcard character. For other file handling functions,
  3281. // the "?" is illegal so we can leave the call alone and let the API itself
  3282. // throw the error and call SetLastError.
  3283. const char c_szAltDefaultChar[] = "<";
  3284. HANDLE __stdcall
  3285. GodotFindFirstFileW(LPCWSTR lpFileName, LPWIN32_FIND_DATAW lpFindFileData)
  3286. {
  3287. // Begin locals
  3288. HANDLE RetVal;
  3289. LPSTR lpFileNameAnsi;
  3290. size_t lpFileNameLength;
  3291. WIN32_FIND_DATAA ffda;
  3292. // Begin precall
  3293. ZeroMemory(&ffda, sizeof(WIN32_FIND_DATAA));
  3294. if (FSTRING_VALID(lpFileName))
  3295. {
  3296. lpFileNameLength = gwcslen(lpFileName)+1;
  3297. _STACKALLOC(lpFileNameLength*g_mcs, lpFileNameAnsi);
  3298. if(lpFileNameAnsi==NULL)
  3299. {
  3300. return(0);
  3301. }
  3302. WideCharToMultiByte(FILES_CPG,
  3303. WC_DEFAULTCHAR|WC_COMPOSITECHECK, // enable default char handling
  3304. lpFileName,
  3305. lpFileNameLength,
  3306. lpFileNameAnsi,
  3307. lpFileNameLength*g_mcs,
  3308. c_szAltDefaultChar,
  3309. NULL);
  3310. }
  3311. else
  3312. lpFileNameAnsi = (LPSTR)lpFileName;
  3313. RetVal=FindFirstFileA(lpFileNameAnsi, &ffda);
  3314. if(RetVal != INVALID_HANDLE_VALUE)
  3315. Win32FindDataWfromA(lpFindFileData, &ffda);
  3316. // Finished
  3317. return RetVal;
  3318. }
  3319. End=
  3320. [EFunc]
  3321. TemplateName=FindNextFileW
  3322. Begin=
  3323. BOOL __stdcall
  3324. GodotFindNextFileW(HANDLE hFindFile, LPWIN32_FIND_DATAW lpFindFileData)
  3325. {
  3326. // Begin locals
  3327. BOOL RetVal;
  3328. WIN32_FIND_DATAA ffda;
  3329. // Call the 'A' version of the API
  3330. ZeroMemory(&ffda, sizeof(WIN32_FIND_DATAA));
  3331. RetVal=FindNextFileA(hFindFile, &ffda);
  3332. // Begin postcall
  3333. if(RetVal)
  3334. Win32FindDataWfromA(lpFindFileData, &ffda);
  3335. // Finished
  3336. return RetVal;
  3337. }
  3338. End=
  3339. [EFunc]
  3340. TemplateName=FindResourceW
  3341. Begin=
  3342. HRSRC __stdcall
  3343. GodotFindResourceW(HMODULE hModule, LPCWSTR lpName, LPCWSTR lpType)
  3344. {
  3345. // We must wrap this function, see GodotFindResourceExW for more info.
  3346. // Just call through to GodotFindResourceExW with 0 for the language,
  3347. // anyway (which is all the Win9x code does).
  3348. return GodotFindResourceExW(hModule, lpType, lpName, 0);
  3349. }
  3350. End=
  3351. [EFunc]
  3352. TemplateName=FindResourceExW
  3353. Begin=
  3354. HRSRC __stdcall
  3355. GodotFindResourceExW(HMODULE hModule, LPCWSTR lpType, LPCWSTR lpName, WORD wLanguage)
  3356. {
  3357. // We must wrap this function, even though it works on Win9x as
  3358. // Unicode, due to OSR v 4.1 bug # 92854. They were always calling
  3359. // LocalFree without alloc'ing, which corrupts the heap.
  3360. if (FWIN95_OR_98())
  3361. {
  3362. // Copy the params to stack variables. Win95/Win98 will fail in
  3363. // their call to LocalFree, but they ignore failure in teardown.
  3364. LPWSTR lpTypeC, lpNameC;
  3365. HRSRC RetVal;
  3366. if(FSTRING_VALID(lpType))
  3367. {
  3368. _STACKALLOC((gwcslen(lpType) + 1) * sizeof(WCHAR), lpTypeC);
  3369. if(lpTypeC==NULL)
  3370. {
  3371. return(0);
  3372. }
  3373. gwcscpy(lpTypeC, lpType);
  3374. }
  3375. else
  3376. lpTypeC = (LPWSTR)lpType;
  3377. if(FSTRING_VALID(lpName))
  3378. {
  3379. _STACKALLOC((gwcslen(lpName) + 1) * sizeof(WCHAR), lpNameC);
  3380. if(lpNameC==NULL)
  3381. {
  3382. return(0);
  3383. }
  3384. gwcscpy(lpNameC, lpName);
  3385. }
  3386. else
  3387. lpNameC = (LPWSTR)lpName;
  3388. RetVal = FindResourceExW(hModule, lpTypeC, lpNameC, wLanguage);
  3389. // If the last error is invalid handle but the function succeeded, then lets
  3390. // assume it came from the bogus LocalFree call and clear things out here.
  3391. if ((RetVal != 0) && (GetLastError() == ERROR_INVALID_HANDLE))
  3392. SetLastError(ERROR_SUCCESS);
  3393. return (RetVal);
  3394. }
  3395. // WinME case
  3396. return FindResourceExW(hModule, lpType, lpName, wLanguage);
  3397. }
  3398. End=
  3399. [EFunc]
  3400. TemplateName=FindTextW
  3401. Begin=
  3402. HWND __stdcall
  3403. GodotFindTextW(LPFINDREPLACEW lpfr)
  3404. {
  3405. return(FindReplaceTextHelper(lpfr, TRUE));
  3406. }
  3407. End=
  3408. [EFunc]
  3409. TemplateName=FindWindowW
  3410. Begin=
  3411. HWND __stdcall
  3412. GodotFindWindowW(LPCWSTR lpszClass, LPCWSTR lpszWindow)
  3413. {
  3414. LPSTR lpszClassAnsi, lpszWindowAnsi;
  3415. GODOT_TO_ACP_STACKALLOC(lpszClass, lpszClassAnsi);
  3416. GODOT_TO_ACP_STACKALLOC(lpszWindow, lpszWindowAnsi);
  3417. if((!lpszClassAnsi && lpszClass) ||
  3418. (!lpszWindowAnsi && lpszWindow))
  3419. return(0);
  3420. return(FindWindowA(lpszClassAnsi, lpszWindowAnsi));
  3421. }
  3422. End=
  3423. [EFunc]
  3424. TemplateName=FindWindowExW
  3425. Begin=
  3426. HWND __stdcall
  3427. GodotFindWindowExW(HWND hwndParent, HWND hwndChildAfter, LPCWSTR lpszClass, LPCWSTR lpszWindow)
  3428. {
  3429. LPSTR lpszClassAnsi, lpszWindowAnsi;
  3430. GODOT_TO_ACP_STACKALLOC(lpszClass, lpszClassAnsi);
  3431. GODOT_TO_ACP_STACKALLOC(lpszWindow, lpszWindowAnsi);
  3432. if((!lpszClassAnsi && lpszClass) ||
  3433. (!lpszWindowAnsi && lpszWindow))
  3434. return(0);
  3435. return(FindWindowExA(hwndParent, hwndChildAfter, lpszClassAnsi, lpszWindowAnsi));
  3436. }
  3437. End=
  3438. [EFunc]
  3439. TemplateName=FormatMessageW
  3440. Begin=
  3441. DWORD __stdcall
  3442. GodotFormatMessageW(DWORD dwFlags, LPCVOID lpSource, DWORD dwMsgId,
  3443. DWORD dwLangId, LPWSTR lpBuffer, DWORD nSize,
  3444. va_list * Args)
  3445. {
  3446. LPSTR lpSourceA; // "A" wrapper for lpSource
  3447. va_list * ArgsA; // "A" wrapper for Args
  3448. DWORD RetVal; // the return value
  3449. LPSTR szBuffer; // "A" wrapper for lpBuffer
  3450. UINT cpg; // code page for the conversions, if any
  3451. UINT mcs; // max bytes per character
  3452. LPSTR szScratch = NULL; // Our scratchpad buffer that we keep our strings in
  3453. BOOL fAllocBuffer = (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER);
  3454. // Take care of code page issues, and handle lpSource
  3455. if (dwFlags & FORMAT_MESSAGE_FROM_STRING)
  3456. {
  3457. cpg = g_acp;
  3458. mcs = g_mcs;
  3459. GODOT_TO_ACP_STACKALLOC(lpSource, lpSourceA);
  3460. }
  3461. else
  3462. {
  3463. cpg = CpgFromLocale(dwLangId);
  3464. mcs = CbPerChOfCpg(cpg);
  3465. lpSourceA = (LPSTR)lpSource;
  3466. }
  3467. // First lets take care of Args, if we need to
  3468. if((Args == NULL) || (dwFlags & FORMAT_MESSAGE_IGNORE_INSERTS))
  3469. {
  3470. // They passed in no args, so lets give them no Args!
  3471. ArgsA = NULL;
  3472. szScratch = NULL;
  3473. }
  3474. else
  3475. {
  3476. PVOID pBuffer = NULL;
  3477. // Ok, what we have to do here is call FormatMessage and ignore
  3478. // inserts so we can get the unformatted string. We will use it
  3479. // later to get arg counts and find out which args are strings.
  3480. RetVal = FormatMessageA((dwFlags | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER),
  3481. lpSourceA,
  3482. dwMsgId,
  3483. dwLangId,
  3484. (char*)&pBuffer,
  3485. nSize,
  3486. NULL);
  3487. if(RetVal == 0)
  3488. {
  3489. // We did not even make it THIS far; lets give up
  3490. return(0);
  3491. }
  3492. else
  3493. {
  3494. UINT rgConv[MAXINSERTS];
  3495. LPSTR pch;
  3496. UINT cItems = 0;
  3497. UINT cStrings = 0;
  3498. // Init the shadow array: this way any inserts not
  3499. // included will default to non-string parameters
  3500. ZeroMemory(rgConv, (sizeof(UINT) * (MAXINSERTS)));
  3501. // Ok, pBuffer points to the string. Use it, filling rgbString so we know
  3502. // whether each param is a string or not, and also so we know the count
  3503. for (pch = (LPSTR)pBuffer; *pch; pch++)
  3504. {
  3505. CHAR szNum[2];
  3506. UINT iNum;
  3507. if (*pch == L'%')
  3508. {
  3509. pch++;
  3510. // Found an insertion. Get the digit or two.
  3511. if (*pch == '0')
  3512. continue; // "%0" is special
  3513. if (*pch < '0' || *pch > '9')
  3514. {
  3515. // skip % followed by nondigit
  3516. continue;
  3517. }
  3518. szNum[0] = '\0';
  3519. szNum[1] = '\0';
  3520. // Move one past the digit we just detected
  3521. pch++;
  3522. if (*pch >= '0' && *pch <= '9')
  3523. {
  3524. // Move one past the optional second digit we just
  3525. // detected and lets make those two digits a number
  3526. pch++;
  3527. memcpy(szNum, pch - 2, (sizeof(CHAR) * 2));
  3528. iNum = MiniAtoI(szNum);
  3529. }
  3530. else
  3531. {
  3532. // Its not a digit, so we will just make that one
  3533. // string 'digit' a number
  3534. memcpy(szNum, pch - 1, sizeof(CHAR));
  3535. iNum = MiniAtoI(szNum);
  3536. }
  3537. // We must allow for the fact that there may be more insert
  3538. // tokens then actual inserts. Thus, cItems is no mere count
  3539. // of items, it is a count of possible items? (see Windows
  3540. // Bugs #368881 for details).
  3541. if(cItems < iNum)
  3542. cItems = iNum;
  3543. // See if there is a formatting character
  3544. if (*pch != '!')
  3545. {
  3546. // No optional type spec, so assume its a string
  3547. rgConv[iNum - 1]=1;
  3548. cStrings++;
  3549. if(*pch == '\0')
  3550. break;
  3551. // Make sure we do not skip the next character
  3552. // when the for loop increments us in a moment
  3553. pch--;
  3554. }
  3555. else
  3556. {
  3557. // See "printf Type Field Characters" for details on our support here.
  3558. // Note that e, E, f, G, and g are not supported by FormatMessage, so
  3559. // everything we care about is either an int, UINT, or string.
  3560. // Skip the exclamation point itself to get the formatting character
  3561. pch++;
  3562. switch(*pch)
  3563. {
  3564. case 'c':
  3565. case 'C':
  3566. case 's':
  3567. case 'S':
  3568. rgConv[iNum - 1]=1;
  3569. cStrings++;
  3570. break;
  3571. case 'd':
  3572. case 'i':
  3573. case 'u':
  3574. case 'o':
  3575. case 'x':
  3576. case 'X':
  3577. default:
  3578. rgConv[iNum - 1]=0;
  3579. break;
  3580. }
  3581. // Skip on past the formatting character (which ought
  3582. // to put us on the closing exclamation point).
  3583. pch++;
  3584. }
  3585. }
  3586. }
  3587. //free the buffer now
  3588. LocalFree(pBuffer);
  3589. if(cItems == 0)
  3590. {
  3591. // They passed in no args in their call even though
  3592. // they said they had some, so lets give them no Args.
  3593. ArgsA = NULL;
  3594. szScratch = NULL;
  3595. }
  3596. else
  3597. {
  3598. ULONG rgpInserts[MAXINSERTS]; // our own argument array of inserts
  3599. UINT idxInsert; // index of the insert we are working on
  3600. DWORD dwOffset = 0; // number of bytes used in rgszInsert
  3601. if(cStrings)
  3602. {
  3603. szScratch = GodotHeapAlloc(CCHMAXPERINSERT * cStrings);
  3604. if(szScratch == NULL)
  3605. {
  3606. SetLastError(ERROR_OUTOFMEMORY);
  3607. return(0);
  3608. }
  3609. }
  3610. for (idxInsert = 0 ; idxInsert < cItems; idxInsert++)
  3611. {
  3612. LPWSTR lpwzT;
  3613. // If this is an arg array, than treat Args like an array of LPWSTRs
  3614. // and read the Args one at a time that way. Otherwise, use va_arg to
  3615. // pick off the next item.
  3616. if (dwFlags & FORMAT_MESSAGE_ARGUMENT_ARRAY)
  3617. lpwzT = (LPWSTR)Args[idxInsert];
  3618. else
  3619. lpwzT = va_arg(*Args, LPWSTR);
  3620. if(rgConv[idxInsert]==1)
  3621. {
  3622. // Convert strings W->A
  3623. UINT cbInsert = WideCharToMultiByte(cpg,
  3624. 0,
  3625. lpwzT,
  3626. -1,
  3627. (LPSTR)(szScratch + dwOffset),
  3628. CCHMAXPERINSERT,
  3629. NULL,
  3630. NULL);
  3631. rgpInserts[idxInsert] = (ULONG)(LPSTR)(szScratch + dwOffset);
  3632. dwOffset += cbInsert;
  3633. }
  3634. else
  3635. {
  3636. // Copy the data, directly. No conversion needed (or even wanted)
  3637. rgpInserts[idxInsert] = (UINT)lpwzT;
  3638. }
  3639. }
  3640. // We have allocated (CCHMAXPERINSERT * cStrings) bytes of space but we only need
  3641. // dwOffset bytes. Lets shrink the buffer to give back as much space as we can.
  3642. if(dwOffset < CCHMAXPERINSERT)
  3643. szScratch = (LPSTR)GodotHeapReAlloc(szScratch, dwOffset+1);
  3644. // We are turning this into an argument array list, so set the flags that way
  3645. dwFlags |= FORMAT_MESSAGE_ARGUMENT_ARRAY;
  3646. ArgsA = (va_list *)rgpInserts;
  3647. }
  3648. }
  3649. }
  3650. if (fAllocBuffer)
  3651. {
  3652. // Must pass address of szBuffer so the API can fill it in. We will
  3653. // then copy it to our own LocalAlloc'ed buffer and free the OS one.
  3654. szBuffer = NULL;
  3655. RetVal=FormatMessageA(dwFlags,
  3656. lpSourceA,
  3657. dwMsgId,
  3658. dwLangId,
  3659. (char*)&szBuffer,
  3660. (mcs * nSize),
  3661. ArgsA);
  3662. }
  3663. else
  3664. {
  3665. // Must alloc szBuffer ourselves
  3666. _STACKALLOC((mcs * nSize), szBuffer);
  3667. if(szBuffer==NULL)
  3668. {
  3669. if(szScratch)
  3670. GodotHeapFree(szScratch);
  3671. // The API will have changed the last error; reset
  3672. // it to the stack overflow so they will know why
  3673. // we failed
  3674. SetLastError(ERROR_STACK_OVERFLOW);
  3675. return(FALSE);
  3676. }
  3677. RetVal=FormatMessageA(dwFlags,
  3678. lpSourceA,
  3679. dwMsgId,
  3680. dwLangId,
  3681. szBuffer,
  3682. (mcs * nSize),
  3683. ArgsA);
  3684. }
  3685. if (!RetVal)
  3686. {
  3687. if(fAllocBuffer)
  3688. {
  3689. lpBuffer = NULL;
  3690. }
  3691. else
  3692. {
  3693. if (FSTRING_VALID(lpBuffer) && (0 < nSize))
  3694. *lpBuffer = L'\0';
  3695. }
  3696. }
  3697. else
  3698. {
  3699. if (fAllocBuffer)
  3700. {
  3701. // szBuffer contains a LocalAlloc'ed ptr to new string. lpBuffer is a
  3702. // WCHAR** when FORMAT_MESSAGE_ALLOCATE_BUFFER is defined. To act like
  3703. // the API, we LocalAlloc our own buffer for the caller.
  3704. WCHAR* lpBufferT = (WCHAR*)LocalAlloc(NONZEROLPTR, (RetVal + 1) * sizeof(WCHAR));
  3705. if(lpBufferT == NULL)
  3706. RetVal = 0;
  3707. else
  3708. {
  3709. if(RetVal = MultiByteToWideChar(g_acp, 0, szBuffer, -1, lpBufferT, RetVal+1))
  3710. RetVal--;
  3711. lpBufferT[RetVal] = L'\0';
  3712. *(WCHAR**)lpBuffer = lpBufferT;
  3713. }
  3714. // free up the buffer the OS created, since we created our own for the user.
  3715. LocalFree(szBuffer);
  3716. }
  3717. else
  3718. {
  3719. // Just convert
  3720. RetVal = MultiByteToWideChar(cpg, 0, szBuffer, RetVal, lpBuffer, nSize);
  3721. lpBuffer[RetVal] = L'\0';
  3722. }
  3723. }
  3724. if(szScratch)
  3725. GodotHeapFree(szScratch);
  3726. return(RetVal);
  3727. }
  3728. End=
  3729. [EFunc]
  3730. TemplateName=FreeContextBuffer
  3731. Begin=
  3732. SECURITY_STATUS __stdcall GodotFreeContextBuffer(void * pvContextBuffer)
  3733. {
  3734. // ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
  3735. return(FreeContextBuffer(pvContextBuffer));
  3736. }
  3737. End=
  3738. [EFunc]
  3739. TemplateName=FreeEnvironmentStringsW
  3740. Begin=
  3741. BOOL __stdcall
  3742. GodotFreeEnvironmentStringsW(LPWSTR lpszEnvironmentBlock)
  3743. {
  3744. // Call the free function directly: we cannot thunk since we
  3745. // freed THAT buffer which the OS gave us, long ago.
  3746. // See comments under GodotGetEnvironmentStringsW for details.
  3747. return(GodotHeapFree(lpszEnvironmentBlock));
  3748. }
  3749. End=
  3750. [EFunc]
  3751. TemplateName=GetAltTabInfoW
  3752. Begin=
  3753. BOOL __stdcall
  3754. GodotGetAltTabInfoW(HWND hwnd, int iItem, PALTTABINFO pati, LPWSTR pszItemText, UINT cchItemText)
  3755. {
  3756. // Begin locals
  3757. BOOL RetVal = FALSE;
  3758. if (s_pfnGetAltTabInfoA == NULL)
  3759. {
  3760. // Must allocate stuff for this API call
  3761. s_pfnGetAltTabInfoA = (PFNgatia)GetUserProc("GetAltTabInfoA");
  3762. }
  3763. if (s_pfnGetAltTabInfoA)
  3764. {
  3765. LPSTR pszItemTextAnsi;
  3766. _STACKALLOC((cchItemText*g_mcs)+1, pszItemTextAnsi);
  3767. if(pszItemTextAnsi==NULL)
  3768. {
  3769. return(FALSE);
  3770. }
  3771. RetVal = (s_pfnGetAltTabInfoA(hwnd, iItem, pati, pszItemTextAnsi, cchItemText));
  3772. // Begin postcall
  3773. if (RetVal && (pszItemText != NULL))
  3774. MultiByteToWideChar(g_acp, 0, pszItemTextAnsi, -1, pszItemText, gwcslen(pszItemText));
  3775. }
  3776. else
  3777. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  3778. // Finished
  3779. return RetVal;
  3780. }
  3781. End=
  3782. [EFunc]
  3783. TemplateName=GetAtomNameW
  3784. Begin=
  3785. UINT __stdcall
  3786. GodotGetAtomNameW(ATOM nAtom, LPWSTR lpBuffer, int nSize)
  3787. {
  3788. // Begin locals
  3789. UINT RetVal;
  3790. LPSTR lpBufferAnsi;
  3791. _STACKALLOC((nSize*g_mcs)+1, lpBufferAnsi);
  3792. if(lpBufferAnsi==NULL)
  3793. {
  3794. return(0);
  3795. }
  3796. // Call the 'A' version of the API
  3797. RetVal=GetAtomNameA(nAtom, lpBufferAnsi, nSize);
  3798. // Begin postcall
  3799. if (RetVal)
  3800. MultiByteToWideChar(g_acp, 0, lpBufferAnsi, -1, lpBuffer, nSize);
  3801. // Finished
  3802. return RetVal;
  3803. }
  3804. End=
  3805. [EFunc]
  3806. TemplateName=GetCalendarInfoW
  3807. Begin=
  3808. int __stdcall
  3809. GodotGetCalendarInfoW( LCID Locale,
  3810. CALID Calendar,
  3811. CALTYPE CalType,
  3812. LPWSTR lpCalData,
  3813. int cchData,
  3814. LPDWORD lpValue
  3815. )
  3816. {
  3817. // Begin locals
  3818. int RetVal = 0;
  3819. LPSTR lpCalDataAnsi;
  3820. UINT cpg;
  3821. UINT mcs;
  3822. if (s_pfnGetCalendarInfoA == NULL)
  3823. {
  3824. // Must allocate stuff for this API call
  3825. s_pfnGetCalendarInfoA = (PFNgcia)GetKernelProc("GetCalendarInfoA");
  3826. }
  3827. if (s_pfnGetCalendarInfoA)
  3828. {
  3829. if(CalType & CAL_USE_CP_ACP)
  3830. {
  3831. cpg = g_acp;
  3832. mcs = g_mcs;
  3833. }
  3834. else
  3835. {
  3836. cpg = CpgFromLocale(Locale);
  3837. mcs = CbPerChOfCpg(cpg);
  3838. }
  3839. _STACKALLOC((cchData+1)*mcs, lpCalDataAnsi);
  3840. RetVal = (s_pfnGetCalendarInfoA (Locale,
  3841. Calendar,
  3842. CalType,
  3843. lpCalDataAnsi,
  3844. (cchData*mcs), // We can be optimists, we allocated for it!
  3845. lpValue));
  3846. // Begin postcall
  3847. if (lpCalDataAnsi != 0)
  3848. MultiByteToWideChar(cpg, 0, lpCalDataAnsi, cchData*mcs, lpCalData, cchData);
  3849. }
  3850. else
  3851. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  3852. // Finished
  3853. return RetVal;
  3854. }
  3855. End=
  3856. [EFunc]
  3857. TemplateName=GetCharABCWidthsW
  3858. Begin=
  3859. BOOL __stdcall
  3860. GodotGetCharABCWidthsW(HDC hdc, UINT ichFirst, UINT ichLast, LPABC lpabc)
  3861. {
  3862. BOOL RetVal = FALSE;
  3863. UINT ich;
  3864. CHAR * sz[2];
  3865. UINT cpg = CpgFromHdc(hdc);
  3866. UINT mcs = CbPerChOfCpg(cpg);
  3867. // Do some basic param validation
  3868. if((ichLast < ichFirst) || (!lpabc))
  3869. {
  3870. SetLastError(ERROR_INVALID_PARAMETER);
  3871. return(FALSE);
  3872. }
  3873. for (ich = ichFirst ; ich < ichLast ; ich++)
  3874. {
  3875. // Convert each character and call the API, one at a time. This might kind
  3876. // of suck, perf-wise, but its the best we can do if we want to be able to
  3877. // give them the values they expect from the API.
  3878. sz[0] = '\0';
  3879. sz[1] = '\0';
  3880. WideCharToMultiByte(cpg, 0, (WCHAR *)ich, 1, (LPSTR)&sz, mcs, NULL, NULL);
  3881. RetVal = GetCharABCWidthsA(hdc, ich, ich, &lpabc[ich - ichFirst]);
  3882. if(!RetVal)
  3883. {
  3884. // The function failed, so bail
  3885. break;
  3886. }
  3887. }
  3888. return(RetVal);
  3889. }
  3890. End=
  3891. [EFunc]
  3892. TemplateName=GetCharABCWidthsFloatW
  3893. Begin=
  3894. BOOL __stdcall
  3895. GodotGetCharABCWidthsFloatW(HDC hdc, UINT ichFirst, UINT ichLast, LPABCFLOAT lpABCF)
  3896. {
  3897. BOOL RetVal = FALSE;
  3898. UINT ich;
  3899. CHAR * sz[2];
  3900. UINT cpg = CpgFromHdc(hdc);
  3901. UINT mcs = CbPerChOfCpg(cpg);
  3902. // Do some basic param validation
  3903. if((ichLast < ichFirst) || (!lpABCF))
  3904. {
  3905. SetLastError(ERROR_INVALID_PARAMETER);
  3906. return(FALSE);
  3907. }
  3908. for (ich = ichFirst ; ich < ichLast ; ich++)
  3909. {
  3910. // Convert each character and call the API, one at a time. This might kind
  3911. // of suck, perf-wise, but its the best we can do if we want to be able to
  3912. // give them the values they expect from the API.
  3913. sz[0] = '\0';
  3914. sz[1] = '\0';
  3915. WideCharToMultiByte(cpg, 0, (WCHAR *)ich, 1, (LPSTR)&sz, mcs, NULL, NULL);
  3916. RetVal = GetCharABCWidthsFloatA(hdc, ich, ich, &lpABCF[ich - ichFirst]);
  3917. if(!RetVal)
  3918. {
  3919. // The function failed, so bail
  3920. break;
  3921. }
  3922. }
  3923. return(RetVal);
  3924. }
  3925. End=
  3926. [EFunc]
  3927. TemplateName=GetCharWidthW
  3928. Begin=
  3929. BOOL __stdcall
  3930. GodotGetCharWidthW(HDC hdc, UINT iFirstChar, UINT iLastChar, LPINT lpBuffer)
  3931. {
  3932. // Due to a bug (feature?) in Win95, characters in Symbol/Wingding/other
  3933. // fonts map to 0xf000, while in NT they map to chars in the default
  3934. // codepage. We cannot really change the NT behavior and who would want to
  3935. // change the Win9x behavior, anyway? Too complicated!
  3936. if (iLastChar <= 127)
  3937. {
  3938. if (GetCharWidthA(hdc, iFirstChar, iLastChar, lpBuffer))
  3939. return TRUE;
  3940. }
  3941. // Call the 'W' version of the API here, since it is available
  3942. return(GetCharWidthW(hdc, iFirstChar, iLastChar, lpBuffer));
  3943. }
  3944. End=
  3945. [EFunc]
  3946. TemplateName=GetCharWidthFloatW
  3947. Begin=
  3948. BOOL __stdcall
  3949. GodotGetCharWidthFloatW(HDC hdc, UINT ichFirst, UINT ichLast, PFLOAT pxBuffer)
  3950. {
  3951. BOOL RetVal = FALSE;
  3952. UINT ich;
  3953. CHAR * sz[2];
  3954. UINT cpg = CpgFromHdc(hdc);
  3955. UINT mcs = CbPerChOfCpg(cpg);
  3956. // Do some basic param validation
  3957. if((ichLast < ichFirst) || (!pxBuffer))
  3958. {
  3959. SetLastError(ERROR_INVALID_PARAMETER);
  3960. return(FALSE);
  3961. }
  3962. for (ich = ichFirst ; ich < ichLast ; ich++)
  3963. {
  3964. // Convert each character and call the API, one at a time. This might kind
  3965. // of suck, perf-wise, but its the best we can do if we want to be able to
  3966. // give them the values they expect from the API.
  3967. sz[0] = '\0';
  3968. sz[1] = '\0';
  3969. WideCharToMultiByte(cpg, 0, (WCHAR *)ich, 1, (LPSTR)&sz, mcs, NULL, NULL);
  3970. RetVal = GetCharWidthFloatA(hdc, ich, ich, &pxBuffer[ich - ichFirst]);
  3971. if(!RetVal)
  3972. {
  3973. // The function failed, so bail
  3974. break;
  3975. }
  3976. }
  3977. return(RetVal);
  3978. }
  3979. End=
  3980. [EFunc]
  3981. TemplateName=GetClassInfoW
  3982. Begin=
  3983. BOOL __stdcall
  3984. GodotGetClassInfoW(HINSTANCE hInstance, LPCWSTR lpClassName, LPWNDCLASSW lpwc)
  3985. {
  3986. // Begin locals
  3987. BOOL RetVal;
  3988. LPSTR lpClassNameAnsi;
  3989. WNDCLASSA wca;
  3990. GODOT_TO_ACP_STACKALLOC(lpClassName, lpClassNameAnsi);
  3991. if(!lpClassNameAnsi && lpClassName)
  3992. return(FALSE);
  3993. ZeroMemory(&wca, sizeof(WNDCLASSA));
  3994. RetVal=GetClassInfoA(hInstance, lpClassNameAnsi, &wca);
  3995. // Begin postcall
  3996. if(RetVal)
  3997. {
  3998. memcpy(lpwc, &wca, sizeof(UINT)+sizeof(WNDPROC)+2*sizeof(int)+4*sizeof(HANDLE));
  3999. // See comments at the top of the file for why we are using a
  4000. // static buffer here for menu and class names
  4001. if (FSTRING_VALID(wca.lpszMenuName))
  4002. {
  4003. MultiByteToWideChar(g_acp, 0, wca.lpszMenuName, -1, m_wzMenuName, 256);
  4004. lpwc->lpszMenuName = m_wzMenuName;
  4005. }
  4006. else
  4007. lpwc->lpszMenuName = (LPWSTR)wca.lpszMenuName;
  4008. if (FSTRING_VALID(wca.lpszClassName))
  4009. {
  4010. MultiByteToWideChar(g_acp, 0, wca.lpszClassName, -1, m_wzClassName, 256);
  4011. lpwc->lpszClassName = m_wzClassName;
  4012. }
  4013. else
  4014. lpwc->lpszClassName = (LPWSTR)wca.lpszClassName;
  4015. }
  4016. // Finished
  4017. return RetVal;
  4018. }
  4019. End=
  4020. [EFunc]
  4021. TemplateName=GetClassInfoExW
  4022. Begin=
  4023. BOOL __stdcall
  4024. GodotGetClassInfoExW(HINSTANCE hinst, LPCWSTR lpszClass, LPWNDCLASSEXW lpwce)
  4025. {
  4026. // Begin locals
  4027. BOOL RetVal;
  4028. LPSTR lpszClassAnsi;
  4029. WNDCLASSEXA wcea;
  4030. GODOT_TO_ACP_STACKALLOC(lpszClass, lpszClassAnsi);
  4031. if(!lpszClassAnsi && lpszClass)
  4032. return(FALSE);
  4033. ZeroMemory(&wcea, sizeof(WNDCLASSEXA));
  4034. wcea.cbSize = sizeof(WNDCLASSEXA);
  4035. RetVal=GetClassInfoExA(hinst, lpszClassAnsi, &wcea);
  4036. // Begin postcall
  4037. if(RetVal)
  4038. {
  4039. memcpy(&lpwce->style,
  4040. &wcea.style,
  4041. sizeof(UINT)+sizeof(WNDPROC)+(2*sizeof(int))+(4*sizeof(HANDLE)));
  4042. // See comments at the top of the file for why we are using a
  4043. // static buffer here
  4044. if (FSTRING_VALID(wcea.lpszMenuName))
  4045. {
  4046. MultiByteToWideChar(g_acp, 0, wcea.lpszMenuName, -1, m_wzMenuName, 256);
  4047. lpwce->lpszMenuName = m_wzMenuName;
  4048. }
  4049. else
  4050. lpwce->lpszMenuName = (LPWSTR)wcea.lpszMenuName;
  4051. if (FSTRING_VALID(wcea.lpszClassName))
  4052. {
  4053. MultiByteToWideChar(g_acp, 0, wcea.lpszClassName, -1, m_wzClassName, 256);
  4054. lpwce->lpszClassName = m_wzClassName;
  4055. }
  4056. else
  4057. lpwce->lpszClassName = (LPWSTR)wcea.lpszClassName;
  4058. lpwce->hIconSm = wcea.hIconSm;
  4059. }
  4060. // Finished
  4061. return RetVal;
  4062. }
  4063. End=
  4064. [EFunc]
  4065. TemplateName=GetClassLongW
  4066. Begin=
  4067. DWORD __stdcall
  4068. GodotGetClassLongW(HWND hWnd, int nIndex)
  4069. {
  4070. // Begin locals
  4071. DWORD RetVal;
  4072. RetVal=GetClassLongA(hWnd, nIndex);
  4073. if((RetVal != 0) && (nIndex == GCL_MENUNAME))
  4074. {
  4075. // We need to convert this string to Unicode and stick it in
  4076. // our global buffer, then return the pointer to that buffer.
  4077. // See comments at the dec. of g_szMenuName for why things
  4078. // have to be done this way.
  4079. MultiByteToWideChar(g_acp, 0, (LPSTR)RetVal, -1, m_wzMenuName, 256);
  4080. RetVal = (DWORD)m_wzMenuName;
  4081. }
  4082. return(RetVal);
  4083. }
  4084. End=
  4085. [EFunc]
  4086. TemplateName=GetClassNameW
  4087. Begin=
  4088. int __stdcall
  4089. GodotGetClassNameW(HWND hWnd, LPWSTR lpClassName, int nMaxCount)
  4090. {
  4091. // Begin locals
  4092. int RetVal;
  4093. LPSTR lpClassNameAnsi;
  4094. _STACKALLOC((nMaxCount*g_mcs)+1, lpClassNameAnsi);
  4095. if(lpClassNameAnsi == NULL)
  4096. {
  4097. return(0);
  4098. }
  4099. // Call the 'A' version of the API
  4100. RetVal=GetClassNameA(hWnd, lpClassNameAnsi, nMaxCount);
  4101. // Begin postcall
  4102. if ((RetVal) && (nMaxCount > 0))
  4103. MultiByteToWideChar(g_acp, 0, lpClassNameAnsi, -1, lpClassName, nMaxCount);
  4104. else
  4105. {
  4106. if (lpClassName && 0 < nMaxCount)
  4107. *lpClassName = L'\0';
  4108. }
  4109. // Finished
  4110. return RetVal;
  4111. }
  4112. End=
  4113. [EFunc]
  4114. TemplateName=GetClipboardData
  4115. Begin=
  4116. HANDLE __stdcall
  4117. GodotGetClipboardData(UINT uFormat)
  4118. {
  4119. HANDLE RetVal = GetClipboardData(uFormat);
  4120. if(RetVal==NULL)
  4121. {
  4122. if((!IsClipboardFormatAvailable(uFormat)) &&
  4123. (GodotIsClipboardFormatAvailable(uFormat)))
  4124. {
  4125. // System says it is not available, but we know better!
  4126. BOOL fUnicodeOnClipboard;
  4127. HANDLE hMemOnClipboard;
  4128. fUnicodeOnClipboard = (uFormat != CF_UNICODETEXT);
  4129. hMemOnClipboard = GetClipboardData(((!fUnicodeOnClipboard) ? CF_TEXT : CF_UNICODETEXT));
  4130. if(hMemOnClipboard != 0)
  4131. {
  4132. // We have a handle to the data, now lets use it.
  4133. PULONG pMemOnClipboard;;
  4134. if(pMemOnClipboard = GlobalLock(hMemOnClipboard))
  4135. {
  4136. HANDLE hLocale = GetClipboardData(CF_LOCALE);
  4137. UINT cpg;
  4138. UINT mcs;
  4139. size_t cb;
  4140. HANDLE hMemSynthetic;
  4141. // Figure out the code page to use now -- this is where we care whether
  4142. // the caller wanted CF_TEXT vs. CF_OEMTEXT -- since it determines
  4143. // whether we want ACP or OEMCP.
  4144. // If they want Unicode then we can grab either one (Win9x supports
  4145. // synthetic conversions CF_TEXT <---> CF_OEMTEXT) so we choose CF_TEXT.
  4146. if(fUnicodeOnClipboard && (uFormat==CF_OEMTEXT))
  4147. cpg = (hLocale ? (CpgOemFromLocale((LCID)(&hLocale))) : g_oemcp);
  4148. else
  4149. cpg = (hLocale ? (CpgFromLocale((LCID)(&hLocale))) : g_acp);
  4150. mcs = CbPerChOfCpg(cpg);
  4151. // Get the appropriate buffer size, based on the existing format and the
  4152. // size of the actual data. This may be bigger than we need it to be if
  4153. // the cpg is a DBCS code page.
  4154. if(fUnicodeOnClipboard)
  4155. cb = gwcslen((LPWSTR)pMemOnClipboard) * mcs;
  4156. else
  4157. cb = lstrlenA((LPSTR)pMemOnClipboard) * sizeof(WCHAR);
  4158. // Allocate some memory for the converted string and then lock it
  4159. if(hMemSynthetic = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, cb))
  4160. {
  4161. PULONG pMemSynthetic = GlobalLock(hMemSynthetic);
  4162. if(pMemSynthetic == NULL)
  4163. {
  4164. // Lock failed, no need to go further, lets bail.
  4165. GlobalFree(hMemSynthetic);
  4166. }
  4167. else
  4168. {
  4169. if(fUnicodeOnClipboard)
  4170. {
  4171. WideCharToMultiByte(cpg,
  4172. 0,
  4173. (LPWSTR)pMemOnClipboard,
  4174. -1,
  4175. (LPSTR)pMemSynthetic,
  4176. cb,
  4177. NULL,
  4178. NULL);
  4179. }
  4180. else
  4181. {
  4182. MultiByteToWideChar(cpg,
  4183. 0,
  4184. (LPSTR)pMemOnClipboard,
  4185. -1,
  4186. (LPWSTR)pMemSynthetic,
  4187. (cb / sizeof(WCHAR)));
  4188. }
  4189. // We made it this far, we will now stick the data on the
  4190. // clipboard. The function thankfully returns the handle
  4191. // to the clipboard object that has just been set. Which is
  4192. // just what the caller wants!
  4193. // CONSIDER: Call GlobalReAlloc when FDBCS_CPG(cpg)? In that
  4194. // case, the buffer may be larger than it has to be.
  4195. RetVal = SetClipboardData(uFormat, pMemSynthetic);
  4196. GlobalUnlock(hMemSynthetic);
  4197. }
  4198. }
  4199. GlobalUnlock(hMemOnClipboard);
  4200. }
  4201. }
  4202. }
  4203. }
  4204. return(RetVal);
  4205. }
  4206. End=
  4207. [EFunc]
  4208. TemplateName=GetClipboardFormatNameW
  4209. Begin=
  4210. int __stdcall
  4211. GodotGetClipboardFormatNameW(UINT format, LPWSTR lpszFormatName, int cchMaxCount)
  4212. {
  4213. // Begin locals
  4214. int RetVal;
  4215. LPSTR lpszFormatNameAnsi;
  4216. _STACKALLOC((cchMaxCount*g_mcs)+1, lpszFormatNameAnsi);
  4217. if(lpszFormatNameAnsi==NULL)
  4218. {
  4219. SetLastError(ERROR_STACK_OVERFLOW);
  4220. return(0);
  4221. }
  4222. ZeroMemory(lpszFormatNameAnsi, (cchMaxCount*g_mcs)+1);
  4223. RetVal=GetClipboardFormatNameA(format, lpszFormatNameAnsi, cchMaxCount);
  4224. // Begin postcall
  4225. if(RetVal)
  4226. MultiByteToWideChar(g_acp, 0, lpszFormatNameAnsi, -1, lpszFormatName, cchMaxCount);
  4227. else
  4228. *lpszFormatName = L'\0';
  4229. // Finished
  4230. return RetVal;
  4231. }
  4232. End=
  4233. [EFunc]
  4234. TemplateName=GetComputerNameW
  4235. Begin=
  4236. BOOL __stdcall
  4237. GodotGetComputerNameW(LPWSTR lpBuffer, LPDWORD nSize)
  4238. {
  4239. BOOL RetVal;
  4240. LPSTR lpBufferAnsi;
  4241. WCHAR wzBuffer[MAX_COMPUTERNAME_LENGTH + 1];
  4242. DWORD nSizeT = MAX_COMPUTERNAME_LENGTH + 1;
  4243. // We will get the full string, always. Win9x is documented as
  4244. // failing if the input size is less than MAX_COMPUTERNAME_LENGTH + 1.
  4245. _STACKALLOC((nSizeT * g_mcs) + 1, lpBufferAnsi);
  4246. if(lpBufferAnsi==NULL)
  4247. {
  4248. SetLastError(ERROR_STACK_OVERFLOW);
  4249. return(0);
  4250. }
  4251. ZeroMemory(lpBufferAnsi, (nSizeT * g_mcs) + 1);
  4252. ZeroMemory(wzBuffer, nSizeT * sizeof(WCHAR));
  4253. RetVal=GetComputerNameA(lpBufferAnsi, &nSizeT);
  4254. // Begin postcall
  4255. if(RetVal)
  4256. {
  4257. MultiByteToWideChar(g_acp,
  4258. 0,
  4259. lpBufferAnsi,
  4260. nSizeT + 1,
  4261. wzBuffer,
  4262. MAX_COMPUTERNAME_LENGTH);
  4263. if(*nSize >= nSizeT)
  4264. {
  4265. // Their buffer is big enough, so copy it over
  4266. gwcscpy(lpBuffer, wzBuffer);
  4267. *nSize = gwcslen(wzBuffer);
  4268. }
  4269. else
  4270. {
  4271. // The A call succeeded, but we need to make it fail
  4272. // since they did not give us enough buffer. So act
  4273. // like the API does and return the size plus the null
  4274. *nSize = gwcslen(wzBuffer) + 1;
  4275. RetVal = 0;
  4276. SetLastError(ERROR_BUFFER_OVERFLOW);
  4277. }
  4278. }
  4279. else
  4280. *lpBuffer = L'0';
  4281. // Finished
  4282. return RetVal;
  4283. }
  4284. End=
  4285. [EFunc]
  4286. TemplateName=GetConsoleTitleW
  4287. Begin=
  4288. DWORD __stdcall
  4289. GodotGetConsoleTitleW(LPWSTR lpConsoleTitle, DWORD nSize)
  4290. {
  4291. // Begin locals
  4292. DWORD RetVal;
  4293. LPSTR lpConsoleTitleAnsi;
  4294. _STACKALLOC((nSize*g_mcs)+1, lpConsoleTitleAnsi);
  4295. if(lpConsoleTitleAnsi==NULL)
  4296. {
  4297. return(0);
  4298. }
  4299. RetVal=GetConsoleTitleA(lpConsoleTitleAnsi, nSize);
  4300. // Begin postcall
  4301. if(RetVal && lpConsoleTitle)
  4302. MultiByteToWideChar(g_oemcp, 0, lpConsoleTitleAnsi, -1, lpConsoleTitle, nSize);
  4303. // Finished
  4304. return RetVal;
  4305. }
  4306. End=
  4307. [EFunc]
  4308. TemplateName=GetCPInfo
  4309. Begin=
  4310. // GetCPInfo is wrapped for UTF-7/UTF-8 support
  4311. BOOL __stdcall
  4312. GodotGetCPInfo(UINT CodePage, LPCPINFO lpCPInfo)
  4313. {
  4314. // See if it's a special code page value for UTF translations.
  4315. if (CodePage >= NLS_CP_ALGORITHM_RANGE)
  4316. return (UTFCPInfo(CodePage, lpCPInfo, FALSE));
  4317. if (CodePage == CP_GB18030)
  4318. return (GB18030Helper(CodePage, NLS_CP_CPINFO, NULL, 0, NULL, 0, lpCPInfo));
  4319. return (GetCPInfo(CodePage, lpCPInfo));
  4320. }
  4321. End=
  4322. [EFunc]
  4323. TemplateName=GetCPInfoExW
  4324. Begin=
  4325. CONST WCHAR szUTF7[] = L"UTF-7";
  4326. CONST WCHAR szUTF8[] = L"UTF-8";
  4327. CONST WCHAR szGB18030[] = L"GB 18030";
  4328. // GetCPInfoExW is wrapped for UTF-7/UTF-8 support, because its on not on Win95,
  4329. // AND for the string containing the code page names, as well. Note that we
  4330. // hardcode the UTF strings rather than make them resources since they are not
  4331. // localized
  4332. BOOL __stdcall
  4333. GodotGetCPInfoExW(UINT CodePage, DWORD dwFlags, LPCPINFOEXW lpCPInfoEx)
  4334. {
  4335. // Begin locals
  4336. BOOL RetVal = FALSE;
  4337. CPINFOEXA CPInfoExAnsi;
  4338. if (s_pfnGetCPInfoExA == NULL)
  4339. {
  4340. // Must allocate stuff for this API call
  4341. s_pfnGetCPInfoExA = (PFNgciea)GetKernelProc("GetCPInfoExA");
  4342. }
  4343. if (s_pfnGetCPInfoExA)
  4344. {
  4345. //
  4346. // See if it's a special code page value for UTF translations.
  4347. //
  4348. if (CodePage >= NLS_CP_ALGORITHM_RANGE)
  4349. {
  4350. if (UTFCPInfo(CodePage, (LPCPINFO)lpCPInfoEx, TRUE))
  4351. {
  4352. if (CodePage == CP_UTF8)
  4353. memcpy(lpCPInfoEx->CodePageName, szUTF8, gwcslen(szUTF8));
  4354. else // (CodePage == CP_UTF7)
  4355. memcpy(lpCPInfoEx->CodePageName, szUTF7, gwcslen(szUTF7));
  4356. return (TRUE);
  4357. }
  4358. return (FALSE);
  4359. }
  4360. if (CodePage == CP_GB18030)
  4361. {
  4362. if (GB18030Helper(CodePage, NLS_CP_CPINFO, NULL, 0, NULL, 0, (LPCPINFO)lpCPInfoEx))
  4363. {
  4364. memcpy(lpCPInfoEx->CodePageName, szGB18030, gwcslen(szGB18030));
  4365. return(TRUE);
  4366. }
  4367. return(FALSE);
  4368. }
  4369. ZeroMemory(&CPInfoExAnsi, sizeof(CPINFOEXA));
  4370. RetVal = (s_pfnGetCPInfoExA(CodePage, dwFlags, &CPInfoExAnsi));
  4371. // Begin postcall
  4372. if(RetVal != FALSE)
  4373. {
  4374. lpCPInfoEx->MaxCharSize = CPInfoExAnsi.MaxCharSize;
  4375. lpCPInfoEx->DefaultChar[0] = CPInfoExAnsi.DefaultChar[0];
  4376. lpCPInfoEx->DefaultChar[1] = CPInfoExAnsi.DefaultChar[1];
  4377. lpCPInfoEx->LeadByte[0] = CPInfoExAnsi.LeadByte[0];
  4378. lpCPInfoEx->LeadByte[1] = CPInfoExAnsi.LeadByte[1];
  4379. lpCPInfoEx->UnicodeDefaultChar = CPInfoExAnsi.UnicodeDefaultChar;
  4380. lpCPInfoEx->CodePage = CPInfoExAnsi.CodePage;
  4381. MultiByteToWideChar(g_acp, 0, CPInfoExAnsi.CodePageName, -1, lpCPInfoEx->CodePageName, MAX_PATH);
  4382. }
  4383. }
  4384. else
  4385. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  4386. // Finished
  4387. return RetVal;
  4388. }
  4389. End=
  4390. [EFunc]
  4391. TemplateName=GetCurrentDirectoryW
  4392. Begin=
  4393. DWORD __stdcall
  4394. GodotGetCurrentDirectoryW(DWORD nBufferLength, LPWSTR lpBuffer)
  4395. {
  4396. // Begin locals
  4397. DWORD RetVal;
  4398. LPSTR lpBufferAnsi;
  4399. _STACKALLOC((nBufferLength*g_mcs)+1, lpBufferAnsi);
  4400. if(lpBufferAnsi==NULL)
  4401. {
  4402. return(0);
  4403. }
  4404. // Call the 'A' version of the API
  4405. RetVal=GetCurrentDirectoryA(nBufferLength, lpBufferAnsi);
  4406. // Begin postcall
  4407. if(RetVal)
  4408. MultiByteToWideChar(g_acp, 0, lpBufferAnsi, -1, lpBuffer, nBufferLength);
  4409. else if (lpBuffer && 0 < nBufferLength)
  4410. *lpBuffer = L'\0';
  4411. // Finished
  4412. return RetVal;
  4413. }
  4414. End=
  4415. [EFunc]
  4416. TemplateName=GetCurrencyFormatW
  4417. Begin=
  4418. int __stdcall
  4419. GodotGetCurrencyFormatW( LCID Locale,
  4420. DWORD dwFlags,
  4421. LPCWSTR lpValue,
  4422. CURRENCYFMTW * lpFormat,
  4423. LPWSTR lpCurrencyStr,
  4424. int cchCurrency
  4425. )
  4426. {
  4427. // Begin locals
  4428. int RetVal;
  4429. LPSTR lpValueAnsi;
  4430. CURRENCYFMTA * lpFormatAnsi;
  4431. LPSTR lpCurrencyStrAnsi;
  4432. UINT cpg = CpgFromLocale(Locale);
  4433. UINT mcs = CbPerChOfCpg(cpg);
  4434. int cchBuff;
  4435. // Begin precall
  4436. GODOT_TO_CPG_STACKALLOC(lpValue, lpValueAnsi, cpg, mcs);
  4437. if (lpFormat == NULL)
  4438. {
  4439. lpFormatAnsi = NULL;
  4440. }
  4441. else
  4442. {
  4443. _STACKALLOC(sizeof(CURRENCYFMTA), lpFormatAnsi);
  4444. ZeroMemory(lpFormatAnsi, sizeof(CURRENCYFMTA));
  4445. lpFormatAnsi->NumDigits = lpFormat->NumDigits;
  4446. lpFormatAnsi->LeadingZero = lpFormat->LeadingZero;
  4447. lpFormatAnsi->Grouping = lpFormat->Grouping;
  4448. GODOT_TO_CPG_STACKALLOC(lpFormat->lpDecimalSep, lpFormatAnsi->lpDecimalSep, cpg, mcs);
  4449. GODOT_TO_CPG_STACKALLOC(lpFormat->lpThousandSep, lpFormatAnsi->lpThousandSep, cpg, mcs);
  4450. lpFormatAnsi->NegativeOrder = lpFormat->NegativeOrder;
  4451. lpFormatAnsi->PositiveOrder = lpFormat->PositiveOrder;
  4452. GODOT_TO_CPG_STACKALLOC(lpFormat->lpCurrencySymbol, lpFormatAnsi->lpCurrencySymbol, cpg, mcs);
  4453. }
  4454. // Call the 'A' version of the API
  4455. if ((cchCurrency > 0) && FSTRING_VALID(lpCurrencyStr == NULL))
  4456. {
  4457. cchBuff = (cchCurrency*mcs)+1;
  4458. _STACKALLOC(cchBuff, lpCurrencyStrAnsi);
  4459. if(lpCurrencyStrAnsi==NULL)
  4460. {
  4461. return(0);
  4462. }
  4463. ZeroMemory(lpCurrencyStrAnsi, cchBuff);
  4464. RetVal=GetCurrencyFormatA(Locale, dwFlags, lpValueAnsi, lpFormatAnsi, lpCurrencyStrAnsi, cchBuff);
  4465. if (RetVal > 0)
  4466. MultiByteToWideChar(cpg, 0, lpCurrencyStrAnsi, cchCurrency*mcs, lpCurrencyStr, cchCurrency);
  4467. }
  4468. else
  4469. RetVal=GetCurrencyFormatA(Locale, dwFlags, lpValueAnsi, lpFormatAnsi, NULL, 0);
  4470. if((RetVal==0) && lpCurrencyStr && (0 < cchCurrency))
  4471. {
  4472. *lpCurrencyStr = '0';
  4473. }
  4474. // Finished
  4475. return RetVal;
  4476. }
  4477. End=
  4478. [EFunc]
  4479. TemplateName=GetCurrentHwProfileW
  4480. Begin=
  4481. BOOL __stdcall
  4482. GodotGetCurrentHwProfileW(LPHW_PROFILE_INFOW lphpi)
  4483. {
  4484. // Begin locals
  4485. BOOL RetVal = FALSE;
  4486. if (s_pfnGetCurrentHwProfileA == NULL)
  4487. {
  4488. // Must allocate stuff for this API call
  4489. s_pfnGetCurrentHwProfileA = (PFNgchpa)GetAdvapiProc("GetCurrentHwProfileA");
  4490. }
  4491. if (s_pfnGetCurrentHwProfileA)
  4492. {
  4493. HW_PROFILE_INFOA hpia;
  4494. RetVal=(s_pfnGetCurrentHwProfileA(&hpia));
  4495. // Begin postcall
  4496. if(RetVal)
  4497. {
  4498. lphpi->dwDockInfo = hpia.dwDockInfo;
  4499. MultiByteToWideChar(g_acp, 0,
  4500. hpia.szHwProfileGuid, HW_PROFILE_GUIDLEN,
  4501. lphpi->szHwProfileGuid, HW_PROFILE_GUIDLEN);
  4502. MultiByteToWideChar(g_acp, 0,
  4503. hpia.szHwProfileName, MAX_PROFILE_LEN,
  4504. lphpi->szHwProfileName, MAX_PROFILE_LEN);
  4505. }
  4506. }
  4507. else
  4508. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  4509. // Finished
  4510. return RetVal;
  4511. }
  4512. End=
  4513. [EFunc]
  4514. TemplateName=GetCharacterPlacementW
  4515. Begin=
  4516. DWORD __stdcall
  4517. GodotGetCharacterPlacementW( HDC hdc,
  4518. LPCWSTR lpString,
  4519. int nCount,
  4520. int nMaxExtent,
  4521. LPGCP_RESULTSW lpResults,
  4522. DWORD dwFlags
  4523. )
  4524. {
  4525. // Since none of the in params in lpResults need conversion and only ONE out param does,
  4526. // we will simply pass their structure on through and convert the one param if we need to
  4527. DWORD RetVal;
  4528. LPSTR lpStringAnsi;
  4529. LPSTR lpOutStringAnsi;
  4530. size_t lpOutStringLength;
  4531. size_t lStructSizeT;
  4532. BOOL fOutString = (FSTRING_VALID(lpResults->lpOutString));
  4533. UINT cpg = CpgFromHdc(hdc);
  4534. UINT mcs = CbPerChOfCpg(cpg);
  4535. // Begin precall
  4536. if(lpResults->lStructSize < sizeof(LPGCP_RESULTSW))
  4537. {
  4538. SetLastError(ERROR_INVALID_PARAMETER);
  4539. return(0);
  4540. }
  4541. GODOT_TO_CPG_STACKALLOC(lpString, lpStringAnsi, cpg, mcs);
  4542. if(lpStringAnsi==NULL)
  4543. {
  4544. return(0);
  4545. }
  4546. // Cache the struct size so we can restore it later
  4547. lStructSizeT = lpResults->lStructSize;
  4548. lpResults->lStructSize = sizeof(LPGCP_RESULTSA);
  4549. RetVal=GetCharacterPlacementA(hdc,
  4550. lpStringAnsi,
  4551. nCount,
  4552. nMaxExtent,
  4553. (LPGCP_RESULTSA)lpResults,
  4554. dwFlags);
  4555. // restore the struct size
  4556. lpResults->lStructSize = lStructSizeT;
  4557. // We will be a little paranoid in case the API did something to the OUT string
  4558. if (fOutString && (RetVal !=0))
  4559. {
  4560. // If the OUT param is there, we need to make that
  4561. // be a UNICODE string (it is an ANSI one right now)
  4562. if (FSTRING_VALID(lpResults->lpOutString))
  4563. {
  4564. lpOutStringLength = lstrlenA( (LPSTR)lpResults->lpOutString);
  4565. _STACKALLOC(lpOutStringLength * mcs, lpOutStringAnsi);
  4566. strcpy(lpOutStringAnsi, (LPSTR)(lpResults->lpOutString));
  4567. MultiByteToWideChar(cpg,
  4568. 0,
  4569. lpOutStringAnsi,
  4570. -1,
  4571. lpResults->lpOutString,
  4572. nCount);
  4573. }
  4574. }
  4575. else
  4576. lpResults->lpOutString = NULL;
  4577. // Finished
  4578. return RetVal;
  4579. }
  4580. End=
  4581. [EFunc]
  4582. TemplateName=GetDateFormatW
  4583. Begin=
  4584. int __stdcall
  4585. GodotGetDateFormatW( LCID Locale,
  4586. DWORD dwFlags,
  4587. const SYSTEMTIME * lpDate,
  4588. LPCWSTR lpFormat,
  4589. LPWSTR lpDateStr,
  4590. int cchDate
  4591. )
  4592. {
  4593. // Begin locals
  4594. int RetVal;
  4595. LPSTR lpFormatAnsi;
  4596. UINT cpg;
  4597. UINT mcs;
  4598. // Begin precall
  4599. if(dwFlags & LOCALE_USE_CP_ACP)
  4600. {
  4601. cpg = g_acp;
  4602. mcs = g_mcs;
  4603. }
  4604. else
  4605. {
  4606. cpg = CpgFromLocale(Locale);
  4607. mcs = CbPerChOfCpg(cpg);
  4608. }
  4609. GODOT_TO_CPG_STACKALLOC(lpFormat, lpFormatAnsi, cpg, mcs);
  4610. if(FSTRING_VALID(lpDateStr) && (cchDate > 0))
  4611. {
  4612. LPSTR lpDateStrAnsi;
  4613. _STACKALLOC((cchDate+1)*mcs, lpDateStrAnsi);
  4614. if(lpDateStrAnsi==NULL)
  4615. {
  4616. return(0);
  4617. }
  4618. RetVal=GetDateFormatA(Locale, dwFlags, lpDate, lpFormatAnsi, lpDateStrAnsi, ((cchDate+1)*mcs));
  4619. if(RetVal && lpDateStr)
  4620. MultiByteToWideChar(cpg, 0, lpDateStrAnsi, cchDate*mcs, lpDateStr, cchDate);
  4621. }
  4622. else
  4623. {
  4624. RetVal=GetDateFormatA(Locale, dwFlags, lpDate, lpFormatAnsi, NULL, 0);
  4625. }
  4626. if(RetVal==0 && lpDateStr && (0 < cchDate))
  4627. {
  4628. *lpDateStr = '0';
  4629. }
  4630. // Finished
  4631. return RetVal;
  4632. }
  4633. End=
  4634. [EFunc]
  4635. TemplateName=GetDiskFreeSpaceExW
  4636. Begin=
  4637. BOOL __stdcall
  4638. GodotGetDiskFreeSpaceExW( LPCWSTR lpDirectoryName,
  4639. PULARGE_INTEGER lpFreeBytesAvailableToCaller,
  4640. PULARGE_INTEGER lpTotalNumberOfBytes,
  4641. PULARGE_INTEGER lpTotalNumberOfFreeBytes
  4642. )
  4643. {
  4644. if (!lpFreeBytesAvailableToCaller || !lpTotalNumberOfBytes)
  4645. return FALSE;
  4646. if (s_pfnGetDiskFreeSpaceExA == NULL)
  4647. {
  4648. // Must allocate stuff for this API call
  4649. s_pfnGetDiskFreeSpaceExA = (PFNgdfsea)GetKernelProc("GetDiskFreeSpaceExA");
  4650. }
  4651. if (s_pfnGetDiskFreeSpaceExA)
  4652. {
  4653. LPSTR lpDirectoryNameAnsi;
  4654. GODOT_TO_ACP_STACKALLOC(lpDirectoryName, lpDirectoryNameAnsi);
  4655. if(!lpDirectoryNameAnsi && lpDirectoryName)
  4656. return(FALSE);
  4657. return(s_pfnGetDiskFreeSpaceExA(lpDirectoryNameAnsi,
  4658. lpFreeBytesAvailableToCaller,
  4659. lpTotalNumberOfBytes,
  4660. lpTotalNumberOfFreeBytes));
  4661. }
  4662. else
  4663. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  4664. // Finished
  4665. return FALSE;
  4666. }
  4667. End=
  4668. [EFunc]
  4669. TemplateName=GetDlgItemTextW
  4670. Begin=
  4671. UINT __stdcall
  4672. GodotGetDlgItemTextW(HWND hDlg, int nIDDlgItem, LPWSTR lpString, int nMaxCount)
  4673. {
  4674. // Begin locals
  4675. UINT RetVal;
  4676. LPSTR lpStringAnsi;
  4677. _STACKALLOC((nMaxCount*g_mcs)+1, lpStringAnsi);
  4678. if(!lpStringAnsi)
  4679. {
  4680. SetLastError(ERROR_STACK_OVERFLOW);
  4681. return(0);
  4682. }
  4683. ZeroMemory(lpStringAnsi, (nMaxCount*g_mcs)+1);
  4684. // Call the 'A' version of the API
  4685. RetVal=GetDlgItemTextA(hDlg, nIDDlgItem, lpStringAnsi, nMaxCount);
  4686. // Begin postcall
  4687. if(RetVal)
  4688. {
  4689. MultiByteToWideChar(g_acp, 0, lpStringAnsi, -1, lpString, nMaxCount);
  4690. }
  4691. else if (lpString && 0 < nMaxCount)
  4692. {
  4693. *lpString = L'\0';
  4694. }
  4695. // Finished
  4696. return RetVal;
  4697. }
  4698. End=
  4699. [EFunc]
  4700. TemplateName=GetEnvironmentStringsW
  4701. Begin=
  4702. LPWSTR __stdcall
  4703. GodotGetEnvironmentStringsW(void)
  4704. {
  4705. // Begin locals
  4706. LPWSTR RetVal = NULL;
  4707. LPSTR RetValAnsi;
  4708. size_t cch;
  4709. // Call the 'A' version of the API
  4710. RetValAnsi=GetEnvironmentStringsA();
  4711. // Begin postcall
  4712. if (RetValAnsi != NULL)
  4713. {
  4714. // Get the size then alloc some memory on the
  4715. // heap; caller can only free it later by calling
  4716. // FreeEnvironmentStringsW, like the docs say.
  4717. cch = (lstrlenA( RetValAnsi)+1);
  4718. RetVal = GodotHeapAlloc(cch*sizeof(WCHAR));
  4719. if (RetVal != NULL)
  4720. {
  4721. MultiByteToWideChar(g_acp, 0, RetValAnsi, -1, RetVal, cch);
  4722. // On DBCS code pages, this allocation might be bigger than
  4723. // it has to be; if it is, then lets shrink it a bit.
  4724. if(FDBCS_CPG(g_acp))
  4725. {
  4726. size_t cchActual = gwcslen(RetVal);
  4727. if((cchActual + 1) < cch)
  4728. RetVal = (LPWSTR)GodotHeapReAlloc(RetVal, cchActual+1);
  4729. }
  4730. }
  4731. // free up the string from the OS, we will have
  4732. // the user free our own later
  4733. FreeEnvironmentStringsA(RetValAnsi);
  4734. }
  4735. // Finished
  4736. return RetVal;
  4737. }
  4738. End=
  4739. [EFunc]
  4740. TemplateName=GetEnvironmentVariableW
  4741. Begin=
  4742. DWORD __stdcall
  4743. GodotGetEnvironmentVariableW(LPCWSTR lpName, LPWSTR lpBuffer, DWORD nSize)
  4744. {
  4745. // Begin locals
  4746. DWORD RetVal;
  4747. LPSTR lpNameAnsi;
  4748. LPSTR lpBufferAnsi;
  4749. _STACKALLOC((nSize*g_mcs)+1, lpBufferAnsi);
  4750. if(!lpBufferAnsi)
  4751. {
  4752. SetLastError(ERROR_STACK_OVERFLOW);
  4753. return(0);
  4754. }
  4755. GODOT_TO_ACP_STACKALLOC(lpName, lpNameAnsi);
  4756. if(!lpNameAnsi && lpName)
  4757. return(0);
  4758. RetVal=GetEnvironmentVariableA(lpNameAnsi, lpBufferAnsi, nSize);
  4759. if(RetVal)
  4760. MultiByteToWideChar(g_acp, 0, lpBufferAnsi, -1, lpBuffer, nSize);
  4761. // Finished
  4762. return RetVal;
  4763. }
  4764. End=
  4765. [EFunc]
  4766. TemplateName=GetEnhMetaFileDescriptionW
  4767. Begin=
  4768. UINT __stdcall
  4769. GodotGetEnhMetaFileDescriptionW(HENHMETAFILE hemf, UINT cchBuffer, LPWSTR lpszDescription)
  4770. {
  4771. // Begin locals
  4772. UINT RetVal;
  4773. LPSTR lpszDescriptionAnsi;
  4774. if (lpszDescription != NULL)
  4775. {
  4776. _STACKALLOC((cchBuffer*g_mcs)+1, lpszDescriptionAnsi);
  4777. if(lpszDescriptionAnsi==NULL)
  4778. {
  4779. SetLastError(ERROR_STACK_OVERFLOW);
  4780. return(0);
  4781. }
  4782. ZeroMemory(lpszDescriptionAnsi,(cchBuffer*g_mcs)+1);
  4783. }
  4784. else
  4785. lpszDescriptionAnsi = NULL;
  4786. // Call the 'A' version of the API
  4787. RetVal=GetEnhMetaFileDescriptionA(hemf, cchBuffer, lpszDescriptionAnsi);
  4788. // Begin postcall: munge the return value to what is copied to
  4789. // the caller's buffer
  4790. if (lpszDescription && lpszDescriptionAnsi)
  4791. MultiByteToWideChar(g_acp, 0, lpszDescriptionAnsi, -1, lpszDescription, cchBuffer);
  4792. // Finished
  4793. return RetVal;
  4794. }
  4795. End=
  4796. [EFunc]
  4797. TemplateName=GetEnhMetaFileW
  4798. Begin=
  4799. HENHMETAFILE __stdcall
  4800. GodotGetEnhMetaFileW(LPCWSTR lpszMetaFile)
  4801. {
  4802. LPSTR lpszMetaFileAnsi;
  4803. // Begin precall
  4804. GODOT_TO_ACP_STACKALLOC(lpszMetaFile, lpszMetaFileAnsi);
  4805. if(lpszMetaFileAnsi==NULL)
  4806. {
  4807. return(0);
  4808. }
  4809. return(GetEnhMetaFileA(lpszMetaFileAnsi));
  4810. }
  4811. End=
  4812. [EFunc]
  4813. TemplateName=GetFileAttributesExW
  4814. Begin=
  4815. BOOL __stdcall
  4816. GodotGetFileAttributesExW(LPCWSTR lpFileName, GET_FILEEX_INFO_LEVELS fInfoLevelId, LPVOID lpFileInformation)
  4817. {
  4818. if (s_pfnGetFileAttributesExA == NULL)
  4819. {
  4820. // Must allocate stuff for this API call
  4821. s_pfnGetFileAttributesExA = (PFNgfnaea)GetKernelProc("GetDiskFreeSpaceExA");
  4822. }
  4823. if (s_pfnGetFileAttributesExA)
  4824. {
  4825. LPSTR lpFileNameAnsi;
  4826. GODOT_TO_ACP_STACKALLOC(lpFileName, lpFileNameAnsi);
  4827. if(!lpFileNameAnsi && lpFileName)
  4828. return(FALSE);
  4829. return(s_pfnGetFileAttributesExA(lpFileNameAnsi, fInfoLevelId, lpFileInformation));
  4830. }
  4831. else
  4832. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  4833. return FALSE;
  4834. }
  4835. End=
  4836. [EFunc]
  4837. TemplateName=GetFileTitleW
  4838. Begin=
  4839. short __stdcall
  4840. GodotGetFileTitleW(LPCWSTR lpszFile, LPWSTR lpszTitle, WORD cbBuf)
  4841. {
  4842. // Begin locals
  4843. short RetVal;
  4844. LPSTR lpszFileAnsi;
  4845. LPSTR lpszTitleAnsi;
  4846. _STACKALLOC((cbBuf*g_mcs)+1, lpszTitleAnsi);
  4847. GODOT_TO_ACP_STACKALLOC(lpszFile, lpszFileAnsi);
  4848. if(lpszTitleAnsi==NULL || (lpszFileAnsi == NULL && lpszFile != NULL))
  4849. {
  4850. SetLastError(ERROR_STACK_OVERFLOW);
  4851. return(FALSE);
  4852. }
  4853. RetVal=GetFileTitleA(lpszFileAnsi, lpszTitleAnsi, cbBuf);
  4854. if(RetVal == 0)
  4855. MultiByteToWideChar(g_acp, 0, lpszTitleAnsi, -1, lpszTitle, cbBuf);
  4856. // Finished
  4857. return RetVal;
  4858. }
  4859. End=
  4860. [EFunc]
  4861. TemplateName=GetFileVersionInfoW
  4862. Begin=
  4863. BOOL __stdcall
  4864. GodotGetFileVersionInfoW(LPWSTR lptstrFilename, DWORD dwHandle, DWORD dwLen, LPVOID lpData)
  4865. {
  4866. LPSTR lptstrFilenameAnsi;
  4867. BYTE* pbyt;
  4868. // Make sure we are at least big enough for our special buffer
  4869. if(dwLen <= VERINFO_BUFFER)
  4870. return(FALSE);
  4871. // Begin precall
  4872. GODOT_TO_ACP_STACKALLOC(lptstrFilename, lptstrFilenameAnsi);
  4873. if(lptstrFilenameAnsi==NULL && lptstrFilename != NULL)
  4874. {
  4875. return(FALSE);
  4876. }
  4877. pbyt = (BYTE*)lpData + VERINFO_BUFFER;
  4878. return(GetFileVersionInfoA(lptstrFilenameAnsi, dwHandle, dwLen, (void *)pbyt));
  4879. }
  4880. End=
  4881. [EFunc]
  4882. TemplateName=GetFileVersionInfoSizeW
  4883. Begin=
  4884. DWORD __stdcall
  4885. GodotGetFileVersionInfoSizeW(LPWSTR lptstrFilename, LPDWORD lpdwHandle)
  4886. {
  4887. LPSTR lptstrFilenameAnsi;
  4888. DWORD RetVal;
  4889. // Begin precall
  4890. GODOT_TO_ACP_STACKALLOC(lptstrFilename, lptstrFilenameAnsi);
  4891. if(lptstrFilenameAnsi==NULL && lptstrFilename != NULL)
  4892. {
  4893. return(FALSE);
  4894. }
  4895. RetVal = GetFileVersionInfoSizeA(lptstrFilenameAnsi, lpdwHandle);
  4896. // If the call succeeds, add our scratchpad buffer for subsequent calls
  4897. if(RetVal)
  4898. RetVal += VERINFO_BUFFER;
  4899. return(RetVal);
  4900. }
  4901. End=
  4902. [EFunc]
  4903. TemplateName=GetFullPathNameW
  4904. Begin=
  4905. DWORD __stdcall
  4906. GodotGetFullPathNameW(LPCWSTR lpFileName, DWORD nBufferLength, LPWSTR lpBuffer, LPWSTR * lpFilePart)
  4907. {
  4908. // Begin locals
  4909. DWORD RetVal;
  4910. LPSTR lpFileNameAnsi;
  4911. LPSTR lpBufferAnsi;
  4912. LPSTR * lpFilePartAnsi = NULL;
  4913. WCHAR drive[_MAX_DRIVE];
  4914. WCHAR dir[_MAX_DIR];
  4915. UINT cpg = FILES_CPG;
  4916. _STACKALLOC((nBufferLength*g_mcs)+1, lpBufferAnsi);
  4917. GODOT_TO_CPG_STACKALLOC(lpFileName, lpFileNameAnsi, cpg, g_mcs);
  4918. if((!lpBufferAnsi) ||
  4919. (lpFileName && !lpFileNameAnsi))
  4920. {
  4921. return(0);
  4922. }
  4923. RetVal=GetFullPathNameA(lpFileNameAnsi, nBufferLength, lpBufferAnsi, lpFilePartAnsi);
  4924. if(RetVal)
  4925. {
  4926. MultiByteToWideChar(cpg, 0, lpBufferAnsi, -1, lpBuffer, nBufferLength);
  4927. if(lpFilePart)
  4928. {
  4929. // We ignore lpFilePartAnsi and just derive lpFilePart here
  4930. // (even non-technical folks like CWissink can contribute now and then!)
  4931. gwsplitpath(lpBuffer, drive, dir, NULL, NULL);
  4932. *lpFilePart = lpBuffer + gwcslen(drive) + gwcslen(dir);
  4933. }
  4934. }
  4935. // Finished
  4936. return RetVal;
  4937. }
  4938. End=
  4939. [EFunc]
  4940. TemplateName=GetGlyphOutlineW
  4941. Begin=
  4942. DWORD __stdcall
  4943. GodotGetGlyphOutlineW(HDC hdc, UINT uChar, UINT uFormat, LPGLYPHMETRICS lpgm,
  4944. DWORD cbBuffer, LPVOID lpvBuffer, const MAT2 * lpmat2)
  4945. {
  4946. UINT uCharA = 0;
  4947. UINT cpg;
  4948. UINT mcs;
  4949. cpg = CpgFromHdc(hdc);
  4950. mcs = CbPerChOfCpg(cpg);
  4951. WideCharToMultiByte(cpg, 0, (WCHAR *)&uChar, 1, (CHAR *)&uCharA, mcs, NULL, NULL);
  4952. return(GetGlyphOutlineA(hdc, uCharA, uFormat, lpgm, cbBuffer, lpvBuffer, lpmat2));
  4953. }
  4954. End=
  4955. [EFunc]
  4956. TemplateName=GetICMProfileW
  4957. Begin=
  4958. BOOL __stdcall
  4959. GodotGetICMProfileW(HDC hDC, LPDWORD lpcbName, LPWSTR lpszFilename)
  4960. {
  4961. // Begin locals
  4962. BOOL RetVal;
  4963. LPSTR lpszFilenameAnsi;
  4964. _STACKALLOC((*lpcbName*g_mcs)+1, lpszFilenameAnsi);
  4965. RetVal=GetICMProfileA(hDC, lpcbName, lpszFilenameAnsi);
  4966. // Begin postcall - make sure to set the return buffer
  4967. // to the actual size of the buffer
  4968. if(RetVal && lpszFilenameAnsi && lpszFilename)
  4969. MultiByteToWideChar(g_acp, 0, lpszFilenameAnsi, -1, lpszFilename, *(lpcbName));
  4970. // Finished
  4971. return RetVal;
  4972. }
  4973. End=
  4974. [EFunc]
  4975. TemplateName=GetJobW
  4976. Begin=
  4977. BOOL __stdcall
  4978. GodotGetJobW(HANDLE _noname0, DWORD _noname1, DWORD _noname2, LPBYTE _noname3,
  4979. DWORD _noname4, LPDWORD _noname5)
  4980. {
  4981. // ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
  4982. return(GetJobW(_noname0, _noname1, _noname2, _noname3, _noname4, _noname5));
  4983. }
  4984. End=
  4985. [EFunc]
  4986. TemplateName=GetKerningPairsW
  4987. Begin=
  4988. DWORD __stdcall
  4989. GodotGetKerningPairsW(HDC hdc, DWORD nNumPairs, LPKERNINGPAIR lpkrnpair)
  4990. {
  4991. DWORD RetVal;
  4992. // we do not want to make them allocate more memory
  4993. // than they need to, so we will do this mostly in place
  4994. RetVal=GetKerningPairsA(hdc, nNumPairs, lpkrnpair);
  4995. // Begin postcall
  4996. if((nNumPairs > 0) && (RetVal > 0))
  4997. {
  4998. UINT cpg = CpgFromHdc(hdc);
  4999. UINT mcs = CbPerChOfCpg(cpg);
  5000. WORD wTemp;
  5001. DWORD iPair;
  5002. for (iPair=0 ; iPair < RetVal ; iPair++)
  5003. {
  5004. wTemp = lpkrnpair[iPair].wFirst;
  5005. lpkrnpair[iPair].wFirst = 0;
  5006. MultiByteToWideChar(cpg, 0, &(char)wTemp, mcs, &(WCHAR)lpkrnpair[iPair].wFirst, 1);
  5007. wTemp = lpkrnpair[iPair].wSecond;
  5008. lpkrnpair[iPair].wSecond = 0;
  5009. MultiByteToWideChar(cpg, 0, &(char)wTemp, mcs, &(WCHAR)lpkrnpair[iPair].wSecond, 1);
  5010. }
  5011. }
  5012. return RetVal;
  5013. }
  5014. End=
  5015. [EFunc]
  5016. TemplateName=GetKeyboardLayoutNameW
  5017. Begin=
  5018. BOOL __stdcall
  5019. GodotGetKeyboardLayoutNameW(LPWSTR pwszKLID)
  5020. {
  5021. // Begin locals
  5022. BOOL RetVal;
  5023. LPSTR pwszKLIDAnsi;
  5024. _STACKALLOC((KL_NAMELENGTH *g_mcs)+1, pwszKLIDAnsi);
  5025. if(pwszKLIDAnsi==NULL)
  5026. {
  5027. return(FALSE);
  5028. }
  5029. RetVal=GetKeyboardLayoutNameA(pwszKLIDAnsi);
  5030. // Begin postcall
  5031. if(RetVal)
  5032. MultiByteToWideChar(g_acp, 0, pwszKLIDAnsi, -1, pwszKLID, gwcslen(pwszKLID));
  5033. // Finished
  5034. return RetVal;
  5035. }
  5036. End=
  5037. [EFunc]
  5038. TemplateName=GetKeyNameTextW
  5039. Begin=
  5040. int __stdcall
  5041. GodotGetKeyNameTextW(LONG lParam, LPWSTR lpString, int nSize)
  5042. {
  5043. int RetVal;
  5044. UINT cpg = CpgFromLocale(LOWORD(GetKeyboardLayout(0)));
  5045. UINT mcs = CbPerChOfCpg(cpg);
  5046. LPSTR lpStringAnsi = GodotHeapAlloc((nSize*mcs) + 1);
  5047. if(lpStringAnsi==NULL)
  5048. {
  5049. SetLastError(ERROR_OUTOFMEMORY);
  5050. return(0);
  5051. }
  5052. RetVal=GetKeyNameTextA(lParam, lpStringAnsi, nSize);
  5053. if(RetVal)
  5054. MultiByteToWideChar(cpg, 0, lpStringAnsi, nSize*mcs, lpString, nSize);
  5055. GodotHeapFree(lpStringAnsi);
  5056. return RetVal;
  5057. }
  5058. End=
  5059. [EFunc]
  5060. TemplateName=GetLocaleInfoW
  5061. Begin=
  5062. #define NLS_GET_LCTYPE_VALUE(x) (x & ~(LOCALE_NOUSEROVERRIDE | \
  5063. LOCALE_USE_CP_ACP | \
  5064. LOCALE_RETURN_NUMBER))
  5065. int __stdcall
  5066. GodotGetLocaleInfoW(LCID Locale, LCTYPE LCType, LPWSTR lpLCData, int cchData)
  5067. {
  5068. LCTYPE LCTypeT = NLS_GET_LCTYPE_VALUE(LCType);
  5069. // a little validation LOCALE_RETURN_NUMBER checks
  5070. if ((LCType & LOCALE_RETURN_NUMBER) & (FWIN95()))
  5071. {
  5072. // NT/Win2000 return this error if you ask for a number on a string LCType,
  5073. // So for Win95 we will do the same if you pass this flag at all.
  5074. SetLastError(ERROR_INVALID_FLAGS);
  5075. return (0);
  5076. }
  5077. if((LCTypeT == LOCALE_RETURN_NUMBER) && (LCTypeT == LOCALE_FONTSIGNATURE))
  5078. {
  5079. // Pass back the unconverted number if thats what they are asking for.
  5080. // Also, do not convert font signatures since those are not really strings.
  5081. return(GetLocaleInfoA(Locale, LCType, (LPSTR)lpLCData, cchData));
  5082. }
  5083. else
  5084. {
  5085. int RetVal;
  5086. LPSTR lpLCDataAnsi;
  5087. UINT cpg;
  5088. UINT mcs;
  5089. if (LCType & LOCALE_USE_CP_ACP)
  5090. {
  5091. cpg = g_acp;
  5092. mcs = g_mcs;
  5093. }
  5094. else
  5095. {
  5096. cpg = CpgFromLocale(Locale);
  5097. mcs = CbPerChOfCpg(cpg);
  5098. }
  5099. _STACKALLOC((cchData+1)*mcs, lpLCDataAnsi);
  5100. if(lpLCDataAnsi==NULL)
  5101. {
  5102. return(0);
  5103. }
  5104. RetVal=GetLocaleInfoA(Locale, LCType, lpLCDataAnsi, cchData);
  5105. if (RetVal)
  5106. {
  5107. // Its a string, so lets convert it
  5108. MultiByteToWideChar(cpg, 0, lpLCDataAnsi, cchData*mcs, lpLCData, cchData);
  5109. }
  5110. else if (lpLCData && 0 < cchData)
  5111. {
  5112. *lpLCData = L'\0';
  5113. }
  5114. return RetVal;
  5115. }
  5116. }
  5117. End=
  5118. [EFunc]
  5119. TemplateName=GetLogColorSpaceW
  5120. Begin=
  5121. BOOL __stdcall
  5122. GodotGetLogColorSpaceW(HCOLORSPACE hColorSpace, LPLOGCOLORSPACEW lcsw, DWORD nSize)
  5123. {
  5124. // Begin locals
  5125. BOOL RetVal;
  5126. LOGCOLORSPACEA lcsa;
  5127. ZeroMemory(&lcsa, sizeof(LOGCOLORSPACEA));
  5128. RetVal=GetLogColorSpaceA(hColorSpace, &lcsa, nSize);
  5129. // Begin postcall
  5130. if(RetVal)
  5131. {
  5132. memcpy(lcsw, &lcsa, 6*sizeof(DWORD)+sizeof(LCSCSTYPE)+sizeof(LCSGAMUTMATCH)+sizeof(CIEXYZTRIPLE));
  5133. if(FSTRING_VALID(lcsw->lcsFilename))
  5134. MultiByteToWideChar(g_acp, 0, lcsa.lcsFilename, -1, lcsw->lcsFilename, MAX_PATH);
  5135. }
  5136. // Finished
  5137. return RetVal;
  5138. }
  5139. End=
  5140. [EFunc]
  5141. TemplateName=GetLogicalDriveStringsW
  5142. Begin=
  5143. DWORD __stdcall
  5144. GodotGetLogicalDriveStringsW(DWORD nBufferLength, LPWSTR lpBuffer)
  5145. {
  5146. // Begin locals
  5147. DWORD RetVal;
  5148. LPSTR lpBufferAnsi;
  5149. _STACKALLOC((nBufferLength*g_mcs)+1, lpBufferAnsi);
  5150. if(lpBufferAnsi==NULL)
  5151. {
  5152. return(0);
  5153. }
  5154. RetVal=GetLogicalDriveStringsA(nBufferLength, lpBufferAnsi);
  5155. // Begin postcall
  5156. if(RetVal && (RetVal<=nBufferLength))
  5157. {
  5158. // Do not muck with the return value. We have to hope that the
  5159. // value will accurately tell the caller when their buffer was
  5160. // not big enough.
  5161. MultiByteToWideChar(g_acp, 0, lpBufferAnsi, -1, lpBuffer, nBufferLength);
  5162. }
  5163. // Finished
  5164. return RetVal;
  5165. }
  5166. End=
  5167. [EFunc]
  5168. TemplateName=GetLongPathNameW
  5169. Begin=
  5170. DWORD __stdcall
  5171. GodotGetLongPathNameW(LPCWSTR lpszShortPath, LPWSTR lpszLongPath, DWORD cchBuffer)
  5172. {
  5173. // Begin locals
  5174. DWORD RetVal = 0;
  5175. if (s_pfnGetLongPathNameA == NULL)
  5176. {
  5177. // Must allocate stuff for this API call
  5178. s_pfnGetLongPathNameA = (PFNglpna)GetKernelProc("GetLongPathNameA");
  5179. }
  5180. if (s_pfnGetLongPathNameA)
  5181. {
  5182. LPSTR lpszShortPathAnsi;
  5183. LPSTR lpszLongPathAnsi;
  5184. UINT cpg = FILES_CPG;
  5185. _STACKALLOC((cchBuffer*g_mcs)+1, lpszLongPathAnsi);
  5186. GODOT_TO_CPG_STACKALLOC(lpszShortPath, lpszShortPathAnsi, cpg, g_mcs);
  5187. if(!lpszShortPathAnsi && lpszShortPath)
  5188. return(0);
  5189. RetVal = (s_pfnGetLongPathNameA(lpszShortPathAnsi, lpszLongPathAnsi, cchBuffer));
  5190. if(RetVal && (RetVal<=cchBuffer))
  5191. MultiByteToWideChar(g_acp, 0, lpszLongPathAnsi, -1, lpszLongPath, cchBuffer);
  5192. }
  5193. else
  5194. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  5195. // Finished
  5196. return RetVal;
  5197. }
  5198. End=
  5199. [EFunc]
  5200. TemplateName=GetMenuItemInfoW
  5201. Begin=
  5202. BOOL __stdcall
  5203. GodotGetMenuItemInfoW(HMENU hMenu, UINT uItem, BOOL fByPosition, LPMENUITEMINFOW lpmiiw)
  5204. {
  5205. // Begin locals
  5206. BOOL RetVal;
  5207. MENUITEMINFOA miia;
  5208. BOOL fAlloc = MenuItemInfoAfromW(&miia, lpmiiw);
  5209. RetVal=GetMenuItemInfoA(hMenu, uItem, fByPosition, &miia);
  5210. // Begin postcall
  5211. if(RetVal)
  5212. {
  5213. memcpy(lpmiiw, &miia, (5*sizeof(UINT)+3*sizeof(HANDLE)+sizeof(ULONG_PTR)));
  5214. if(fAlloc)
  5215. {
  5216. MultiByteToWideChar(g_acp, 0, miia.dwTypeData, miia.cch, lpmiiw->dwTypeData, lpmiiw->cch);
  5217. lpmiiw->cch = gwcslen(lpmiiw->dwTypeData);
  5218. }
  5219. else
  5220. {
  5221. lpmiiw->dwTypeData = (LPWSTR)miia.dwTypeData;
  5222. lpmiiw->cch = sizeof(lpmiiw->dwTypeData);
  5223. }
  5224. }
  5225. if(fAlloc)
  5226. GodotHeapFree(miia.dwTypeData);
  5227. // Finished
  5228. return RetVal;
  5229. }
  5230. End=
  5231. [EFunc]
  5232. TemplateName=GetMenuStringW
  5233. Begin=
  5234. int __stdcall
  5235. GodotGetMenuStringW(HMENU hMenu, UINT uIDItem, LPWSTR lpString, int nMaxCount, UINT uFlag)
  5236. {
  5237. // Begin locals
  5238. int RetVal;
  5239. LPSTR lpStringAnsi = NULL;
  5240. _STACKALLOC((nMaxCount * g_mcs) + 1, lpStringAnsi);
  5241. if(lpStringAnsi==NULL)
  5242. {
  5243. return(0);
  5244. }
  5245. ZeroMemory(lpStringAnsi, (nMaxCount * g_mcs) + 1);
  5246. // Call the 'A' version of the API
  5247. RetVal=GetMenuStringA(hMenu, uIDItem, lpStringAnsi, nMaxCount, uFlag);
  5248. // Begin postcall
  5249. if(RetVal && lpStringAnsi && lpString)
  5250. MultiByteToWideChar(g_acp, 0, lpStringAnsi, -1, lpString, (RetVal + 1));
  5251. // Finished
  5252. return RetVal;
  5253. }
  5254. End=
  5255. [EFunc]
  5256. TemplateName=GetMessageW
  5257. Begin=
  5258. BOOL __stdcall
  5259. GodotGetMessageW(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax)
  5260. {
  5261. return(GodotReceiveMessage(mtGetMessage, lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, 0));
  5262. }
  5263. End=
  5264. [EFunc]
  5265. TemplateName=GetModuleFileNameW
  5266. Begin=
  5267. DWORD __stdcall
  5268. GodotGetModuleFileNameW(HMODULE hModule, LPWSTR lpFilename, DWORD nSize)
  5269. {
  5270. // Begin locals
  5271. DWORD RetVal;
  5272. LPSTR lpFilenameAnsi;
  5273. _STACKALLOC((nSize*g_mcs)+1, lpFilenameAnsi);
  5274. if(!lpFilenameAnsi)
  5275. {
  5276. SetLastError(ERROR_STACK_OVERFLOW);
  5277. return(FALSE);
  5278. }
  5279. // Call the 'A' version of the API
  5280. RetVal=GetModuleFileNameA(hModule, lpFilenameAnsi, nSize);
  5281. // Begin postcall. Per the PSDK: For the ANSI version of the function, the number
  5282. // of TCHARs is the number of bytes; for the Unicode version, it is the number of
  5283. // characters.
  5284. // CONSIDER: Optimize the return value for the case where the buffer was not big
  5285. // enough?
  5286. if(RetVal)
  5287. {
  5288. MultiByteToWideChar(g_acp, 0, lpFilenameAnsi, -1, lpFilename, nSize);
  5289. RetVal = gwcslen(lpFilename);
  5290. }
  5291. else if (lpFilename && 0 < nSize)
  5292. *lpFilename = L'\0';
  5293. // Finished
  5294. return RetVal;
  5295. }
  5296. End=
  5297. [EFunc]
  5298. TemplateName=GetMonitorInfoW
  5299. Begin=
  5300. BOOL __stdcall
  5301. GodotGetMonitorInfoW(HMONITOR hMonitor, LPMONITORINFO lpmi)
  5302. {
  5303. // Begin locals
  5304. BOOL RetVal = FALSE;
  5305. if (s_pfnGetMonitorInfoA == NULL)
  5306. {
  5307. // Must allocate stuff for this API call
  5308. s_pfnGetMonitorInfoA = (PFNgmia)GetUserProc("GetMonitorInfoA");
  5309. }
  5310. if (s_pfnGetMonitorInfoA)
  5311. {
  5312. // Only need to convert anything if caller gave us an EX structure
  5313. if(lpmi->cbSize == sizeof(MONITORINFOEXW))
  5314. {
  5315. MONITORINFOEXA mia;
  5316. ZeroMemory(&mia, sizeof(MONITORINFOEXA));
  5317. memcpy(&mia, lpmi, (2 * sizeof(DWORD)) + (2 * (sizeof(RECT))));
  5318. mia.cbSize = sizeof(MONITORINFOEXA);
  5319. WideCharToMultiByte(g_acp, 0,
  5320. ((LPMONITORINFOEXW)lpmi)->szDevice, CCHDEVICENAME,
  5321. mia.szDevice, CCHDEVICENAME,
  5322. NULL, NULL);
  5323. RetVal = (s_pfnGetMonitorInfoA (hMonitor, (LPMONITORINFO)&mia));
  5324. if(RetVal)
  5325. {
  5326. memcpy(lpmi, &mia, (2 * sizeof(DWORD)) + (2 * (sizeof(RECT))));
  5327. MultiByteToWideChar(g_acp, 0,
  5328. mia.szDevice, -1,
  5329. ((LPMONITORINFOEXW)lpmi)->szDevice, CCHDEVICENAME);
  5330. }
  5331. }
  5332. else
  5333. {
  5334. RetVal = (s_pfnGetMonitorInfoA (hMonitor, lpmi));
  5335. }
  5336. }
  5337. else
  5338. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  5339. // Finished
  5340. return RetVal;
  5341. }
  5342. End=
  5343. [EFunc]
  5344. TemplateName=GetObjectW
  5345. Begin=
  5346. int __stdcall
  5347. GodotGetObjectW(HGDIOBJ hgdiobj, int cbBuffer, LPVOID lpvObject)
  5348. {
  5349. // Begin locals
  5350. int RetVal;
  5351. if(GetObjectType(hgdiobj) == OBJ_FONT)
  5352. {
  5353. LOGFONTA lfa;
  5354. RetVal=GetObjectA(hgdiobj, cbBuffer, &lfa);
  5355. if(RetVal==sizeof(LOGFONTA))
  5356. {
  5357. // Make sure they gave us an object and did not lie about the
  5358. // size. Found this bug with the Visio Editor test integration.
  5359. if(lpvObject)
  5360. LogFontWfromA((LPLOGFONTW)lpvObject, &lfa);
  5361. RetVal = sizeof(LOGFONTW);
  5362. }
  5363. }
  5364. else
  5365. {
  5366. RetVal=GetObjectA(hgdiobj, cbBuffer, lpvObject);
  5367. }
  5368. // Finished
  5369. return RetVal;
  5370. }
  5371. End=
  5372. [EFunc]
  5373. TemplateName=GetOpenFileNameW
  5374. Begin=
  5375. BOOL __stdcall
  5376. GodotGetOpenFileNameW(LPOPENFILENAMEW lpofn)
  5377. {
  5378. return(GetOpenSaveFileHelper(lpofn, TRUE));
  5379. }
  5380. End=
  5381. [EFunc]
  5382. TemplateName=GetOpenFileNamePreviewW
  5383. Begin=
  5384. BOOL __stdcall GodotGetOpenFileNamePreviewW(LPOPENFILENAMEW lpofn)
  5385. {
  5386. // ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
  5387. return(FALSE);
  5388. }
  5389. End=
  5390. [EFunc]
  5391. TemplateName=GetNamedPipeHandleStateW
  5392. Begin=
  5393. BOOL __stdcall
  5394. GodotGetNamedPipeHandleStateW( HANDLE hNamedPipe,
  5395. LPDWORD lpState,
  5396. LPDWORD lpCurInstances,
  5397. LPDWORD lpMaxCollectionCount,
  5398. LPDWORD lpCollectDataTimeout,
  5399. LPWSTR lpUserName,
  5400. DWORD nMaxUserNameSize
  5401. )
  5402. {
  5403. // Begin locals
  5404. BOOL RetVal;
  5405. LPSTR lpUserNameAnsi;
  5406. if(lpUserName)
  5407. {
  5408. _STACKALLOC((nMaxUserNameSize*g_mcs)+1, lpUserNameAnsi);
  5409. if(!lpUserNameAnsi)
  5410. {
  5411. SetLastError(ERROR_STACK_OVERFLOW);
  5412. return(FALSE);
  5413. }
  5414. }
  5415. else
  5416. lpUserNameAnsi = NULL;
  5417. RetVal=GetNamedPipeHandleStateA(hNamedPipe,
  5418. lpState,
  5419. lpCurInstances,
  5420. lpMaxCollectionCount,
  5421. lpCollectDataTimeout,
  5422. lpUserNameAnsi,
  5423. nMaxUserNameSize
  5424. );
  5425. // Begin postcall
  5426. if (RetVal && FSTRING_VALID(lpUserName) && FSTRING_VALID(lpUserNameAnsi))
  5427. MultiByteToWideChar(g_acp, 0, lpUserNameAnsi, -1, lpUserName, nMaxUserNameSize);
  5428. // Finished
  5429. return RetVal;
  5430. }
  5431. End=
  5432. [EFunc]
  5433. TemplateName=GetNumberFormatW
  5434. Begin=
  5435. int __stdcall
  5436. GodotGetNumberFormatW( LCID Locale,
  5437. DWORD dwFlags,
  5438. LPCWSTR lpValue,
  5439. const NUMBERFMTW * lpFormat,
  5440. LPWSTR lpNumberStr,
  5441. int cchNumber
  5442. )
  5443. {
  5444. // Begin locals
  5445. int RetVal;
  5446. LPSTR lpValueAnsi;
  5447. UINT cpg = CpgFromLocale(Locale);
  5448. UINT mcs = CbPerChOfCpg(cpg);
  5449. NUMBERFMTA * lpFormatAnsi;
  5450. NUMBERFMTA FormatAnsi;
  5451. // Begin precall
  5452. GODOT_TO_CPG_STACKALLOC(lpValue, lpValueAnsi, cpg, mcs);
  5453. if (lpFormat == NULL)
  5454. lpFormatAnsi = NULL;
  5455. else
  5456. {
  5457. ZeroMemory(&FormatAnsi, sizeof(NUMBERFMTA));
  5458. memcpy(&FormatAnsi, lpFormat, (3*sizeof(UINT)));
  5459. GODOT_TO_CPG_STACKALLOC(lpFormat->lpDecimalSep, FormatAnsi.lpDecimalSep, cpg, mcs);
  5460. GODOT_TO_CPG_STACKALLOC(lpFormat->lpThousandSep, FormatAnsi.lpThousandSep, cpg, mcs);
  5461. FormatAnsi.NegativeOrder = lpFormat->NegativeOrder;
  5462. lpFormatAnsi = &FormatAnsi;
  5463. }
  5464. if ((cchNumber > 0) && FSTRING_VALID(lpNumberStr))
  5465. {
  5466. size_t cchBuff = (cchNumber+1)*mcs;
  5467. LPSTR lpNumberStrAnsi;
  5468. _STACKALLOC(cchBuff, lpNumberStrAnsi);
  5469. if(!lpNumberStrAnsi)
  5470. {
  5471. SetLastError(ERROR_STACK_OVERFLOW);
  5472. return(0);
  5473. }
  5474. RetVal=GetNumberFormatA(Locale, dwFlags, lpValueAnsi, lpFormatAnsi, lpNumberStrAnsi, cchBuff);
  5475. if(RetVal > 0)
  5476. MultiByteToWideChar(cpg, 0, lpNumberStrAnsi, RetVal, lpNumberStr, cchNumber);
  5477. }
  5478. else
  5479. RetVal=GetNumberFormatA(Locale, dwFlags, lpValueAnsi, lpFormatAnsi, NULL, 0);
  5480. // Finished
  5481. return RetVal;
  5482. }
  5483. End=
  5484. [EFunc]
  5485. TemplateName=GetOutlineTextMetricsW
  5486. Begin=
  5487. UINT __stdcall
  5488. GodotGetOutlineTextMetricsW(HDC hdc, UINT cbData, LPOUTLINETEXTMETRICW lpOTM)
  5489. {
  5490. // Begin locals
  5491. UINT RetVal;
  5492. int cOTM;
  5493. LPOUTLINETEXTMETRICA lpOTMAnsi = NULL;
  5494. OUTLINETEXTMETRICW otm;
  5495. int i;
  5496. // Begin precall
  5497. if((lpOTM != NULL) && (cbData > 0))
  5498. {
  5499. cOTM = (sizeof(OUTLINETEXTMETRICW)/cbData);
  5500. _STACKALLOC(sizeof(OUTLINETEXTMETRICA)*cOTM, lpOTMAnsi);
  5501. ZeroMemory(lpOTMAnsi, (sizeof(OUTLINETEXTMETRICA)*cOTM));
  5502. }
  5503. else
  5504. {
  5505. lpOTMAnsi = NULL;
  5506. cOTM = 0;
  5507. }
  5508. // Call the 'A' version of the API
  5509. RetVal=GetOutlineTextMetricsA(hdc, cbData, lpOTMAnsi);
  5510. // Begin postcall
  5511. if (lpOTM == NULL)
  5512. {
  5513. if(RetVal > 0)
  5514. // We need to return something sensible here: the size of
  5515. // OUTLINETEXTMETRICW structures.
  5516. RetVal = (sizeof(OUTLINETEXTMETRICW) * (RetVal / sizeof(OUTLINETEXTMETRICA)));
  5517. }
  5518. else
  5519. {
  5520. if(RetVal > 0 && lpOTMAnsi)
  5521. {
  5522. cOTM = (RetVal / sizeof(OUTLINETEXTMETRICA));
  5523. otm = *lpOTM;
  5524. for (i=0; i < cOTM; i++)
  5525. {
  5526. lpOTM->otmSize = sizeof(OUTLINETEXTMETRICW);
  5527. memcpy(lpOTM, lpOTMAnsi, sizeof(OUTLINETEXTMETRICW));
  5528. TextMetricWfromA(&lpOTM->otmTextMetrics, &lpOTMAnsi->otmTextMetrics);
  5529. lpOTM++;
  5530. lpOTMAnsi++;
  5531. }
  5532. lpOTM = &otm;
  5533. }
  5534. }
  5535. // Finished
  5536. return RetVal;
  5537. }
  5538. End=
  5539. [EFunc]
  5540. TemplateName=GetPrinterW
  5541. Begin=
  5542. BOOL __stdcall
  5543. GodotGetPrinterW(HANDLE _noname0, DWORD _noname1, LPBYTE _noname2, DWORD _noname3, LPDWORD _noname4)
  5544. {
  5545. // ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
  5546. return(GetPrinterW(_noname0, _noname1, _noname2, _noname3, _noname4));
  5547. }
  5548. End=
  5549. [EFunc]
  5550. TemplateName=GetPrinterDataW
  5551. Begin=
  5552. DWORD __stdcall
  5553. GodotGetPrinterDataW(HANDLE _noname0, LPWSTR _noname1, LPDWORD _noname2, LPBYTE _noname3,
  5554. DWORD _noname4, LPDWORD _noname5)
  5555. {
  5556. // ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
  5557. return(GetPrinterDataW(_noname0, _noname1, _noname2, _noname3, _noname4, _noname5));
  5558. }
  5559. End=
  5560. [EFunc]
  5561. TemplateName=GetPrinterDriverW
  5562. Begin=
  5563. BOOL __stdcall
  5564. GodotGetPrinterDriverW(HANDLE _noname0, LPWSTR _noname1, DWORD _noname2, LPBYTE _noname3,
  5565. DWORD _noname4, LPDWORD _noname5)
  5566. {
  5567. // ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
  5568. return(GetPrinterDriverW(_noname0, _noname1, _noname2, _noname3, _noname4, _noname5));
  5569. }
  5570. End=
  5571. [EFunc]
  5572. TemplateName=GetPrinterDriverDirectoryW
  5573. Begin=
  5574. BOOL __stdcall
  5575. GodotGetPrinterDriverDirectoryW( LPWSTR pName,
  5576. LPWSTR pEnvironment,
  5577. DWORD Level,
  5578. LPBYTE pDriverDirectory,
  5579. DWORD cbBuf,
  5580. LPDWORD pcbNeeded
  5581. )
  5582. {
  5583. BOOL RetVal = FALSE;
  5584. LPSTR pNameAnsi = NULL;
  5585. LPSTR pEnvironmentAnsi = NULL;
  5586. LPBYTE pDriverDirectoryA;
  5587. ALLOCRETURN arName;
  5588. ALLOCRETURN arEnvironmentName;
  5589. // cbBuf is number of bytes, which is at a minimum
  5590. // big enough to hold the ANSI string
  5591. _STACKALLOC(cbBuf + 1, pDriverDirectoryA);
  5592. if(pDriverDirectoryA == NULL)
  5593. {
  5594. SetLastError(ERROR_STACK_OVERFLOW);
  5595. return(FALSE);
  5596. }
  5597. arName = GodotToAcpOnHeap(pName, &pNameAnsi);
  5598. arEnvironmentName = GodotToAcpOnHeap(pEnvironment, &pEnvironmentAnsi);
  5599. RetVal=GetPrinterDriverDirectoryA(pNameAnsi,
  5600. pEnvironmentAnsi,
  5601. Level,
  5602. pDriverDirectoryA,
  5603. cbBuf,
  5604. pcbNeeded);
  5605. if(RetVal)
  5606. {
  5607. MultiByteToWideChar(g_acp, 0,
  5608. (LPSTR)pDriverDirectoryA, -1,
  5609. (LPWSTR)pDriverDirectory, cbBuf / sizeof(WCHAR));
  5610. if(pcbNeeded)
  5611. *pcbNeeded = gwcslen((LPWSTR)pDriverDirectory);
  5612. }
  5613. else
  5614. {
  5615. if(pcbNeeded)
  5616. *pcbNeeded *= 2;
  5617. }
  5618. if(arName==arAlloc)
  5619. GodotHeapFree(pNameAnsi);
  5620. if(arEnvironmentName==arAlloc)
  5621. GodotHeapFree(pEnvironmentAnsi);
  5622. if(arName == arFailed || arEnvironmentName == arFailed)
  5623. SetLastError(ERROR_OUTOFMEMORY);
  5624. return RetVal;
  5625. }
  5626. End=
  5627. [EFunc]
  5628. TemplateName=GetPrintProcessorDirectoryW
  5629. Begin=
  5630. BOOL __stdcall
  5631. GodotGetPrintProcessorDirectoryW( LPWSTR pName,
  5632. LPWSTR pEnvironment,
  5633. DWORD Level,
  5634. LPBYTE pPrintProcessorInfo,
  5635. DWORD cbBuf,
  5636. LPDWORD pcbNeeded
  5637. )
  5638. {
  5639. BOOL RetVal = FALSE;
  5640. LPSTR pNameAnsi = NULL;
  5641. LPSTR pEnvironmentAnsi = NULL;
  5642. LPBYTE pPrintProcessorInfoA;
  5643. ALLOCRETURN arName;
  5644. ALLOCRETURN arEnvironmentName;
  5645. // cbBuf is number of bytes, which is at a minimum
  5646. // big enough to hold the ANSI string
  5647. _STACKALLOC(cbBuf + 1, pPrintProcessorInfoA);
  5648. if(pPrintProcessorInfoA == NULL)
  5649. {
  5650. SetLastError(ERROR_STACK_OVERFLOW);
  5651. return(FALSE);
  5652. }
  5653. arName = GodotToAcpOnHeap(pName, &pNameAnsi);
  5654. arEnvironmentName = GodotToAcpOnHeap(pEnvironment, &pEnvironmentAnsi);
  5655. RetVal=GetPrintProcessorDirectoryA(pNameAnsi,
  5656. pEnvironmentAnsi,
  5657. Level,
  5658. pPrintProcessorInfoA,
  5659. cbBuf,
  5660. pcbNeeded);
  5661. if(RetVal)
  5662. {
  5663. MultiByteToWideChar(g_acp, 0,
  5664. (LPSTR)pPrintProcessorInfoA, -1,
  5665. (LPWSTR)pPrintProcessorInfo, cbBuf / sizeof(WCHAR));
  5666. if(pcbNeeded)
  5667. *pcbNeeded = gwcslen((LPWSTR)pPrintProcessorInfo);
  5668. }
  5669. else
  5670. {
  5671. if(pcbNeeded)
  5672. *pcbNeeded *= sizeof(WCHAR);
  5673. }
  5674. if(arName==arAlloc)
  5675. GodotHeapFree(pNameAnsi);
  5676. if(arEnvironmentName==arAlloc)
  5677. GodotHeapFree(pEnvironmentAnsi);
  5678. if(arName == arFailed || arEnvironmentName == arFailed)
  5679. SetLastError(ERROR_OUTOFMEMORY);
  5680. return RetVal;
  5681. }
  5682. End=
  5683. [EFunc]
  5684. TemplateName=GetPrivateProfileSectionW
  5685. Begin=
  5686. DWORD __stdcall
  5687. GodotGetPrivateProfileSectionW(LPCWSTR lpAppName, LPWSTR lpReturnedString, DWORD nSize, LPCWSTR lpFileName)
  5688. {
  5689. // Begin locals
  5690. DWORD RetVal;
  5691. LPSTR lpAppNameAnsi;
  5692. char lpFileNameAnsi[MAX_PATH + 1];
  5693. LPSTR lpReturnedStringAnsi;
  5694. _STACKALLOC((nSize*g_mcs)+1, lpReturnedStringAnsi);
  5695. if(!lpReturnedStringAnsi)
  5696. return(0);
  5697. GODOT_TO_ACP_STACKALLOC(lpAppName, lpAppNameAnsi);
  5698. if(!lpAppNameAnsi && lpAppName)
  5699. {
  5700. SetLastError(ERROR_STACK_OVERFLOW);
  5701. return(0);
  5702. }
  5703. WideCharToMultiByte(g_acp, 0, lpFileName, -1, lpFileNameAnsi, MAX_PATH, NULL, NULL);
  5704. RetVal=GetPrivateProfileSectionA(lpAppNameAnsi, lpReturnedStringAnsi, nSize, lpFileNameAnsi);
  5705. if(RetVal)
  5706. RetVal = GrszToGrwz(lpReturnedStringAnsi, lpReturnedString, nSize);
  5707. else if(lpReturnedString)
  5708. {
  5709. *lpReturnedString = '\0';
  5710. }
  5711. // Finished
  5712. return RetVal;
  5713. }
  5714. End=
  5715. [EFunc]
  5716. TemplateName=GetPrivateProfileSectionNamesW
  5717. Begin=
  5718. DWORD __stdcall
  5719. GodotGetPrivateProfileSectionNamesW(LPWSTR lpszReturnBuffer, DWORD nSize, LPCWSTR lpFileName)
  5720. {
  5721. // Begin locals
  5722. DWORD RetVal;
  5723. char lpFileNameAnsi[MAX_PATH + 1];
  5724. LPSTR lpszReturnBufferAnsi;
  5725. _STACKALLOC((nSize*g_mcs)+1, lpszReturnBufferAnsi);
  5726. if(!lpszReturnBufferAnsi)
  5727. {
  5728. SetLastError(ERROR_STACK_OVERFLOW);
  5729. return(0);
  5730. }
  5731. ZeroMemory(lpszReturnBufferAnsi, (nSize*g_mcs)+1);
  5732. WideCharToMultiByte(g_acp, 0, lpFileName, -1, lpFileNameAnsi, MAX_PATH, NULL, NULL);
  5733. RetVal=GetPrivateProfileSectionNamesA(lpszReturnBufferAnsi, nSize, lpFileNameAnsi);
  5734. if(RetVal)
  5735. RetVal = GrszToGrwz(lpszReturnBufferAnsi, lpszReturnBuffer, nSize);
  5736. else if(lpszReturnBuffer)
  5737. {
  5738. *lpszReturnBuffer = '\0';
  5739. }
  5740. // Finished
  5741. return RetVal;
  5742. }
  5743. End=
  5744. [EFunc]
  5745. TemplateName=GetPrivateProfileStringW
  5746. Begin=
  5747. DWORD __stdcall
  5748. GodotGetPrivateProfileStringW( LPCWSTR lpAppName,
  5749. LPCWSTR lpKeyName,
  5750. LPCWSTR lpDefault,
  5751. LPWSTR lpReturnedString,
  5752. DWORD nSize,
  5753. LPCWSTR lpFileName
  5754. )
  5755. {
  5756. // Begin locals
  5757. DWORD RetVal;
  5758. LPSTR lpAppNameAnsi, lpKeyNameAnsi, lpDefaultAnsi;
  5759. LPSTR lpszRet;
  5760. char lpFileNameAnsi[MAX_PATH + 1];
  5761. _STACKALLOC((nSize*g_mcs)+1, lpszRet);
  5762. if(lpszRet==NULL)
  5763. {
  5764. return(0);
  5765. }
  5766. WideCharToMultiByte(g_acp, 0, lpFileName, -1, lpFileNameAnsi, MAX_PATH, NULL, NULL);
  5767. GODOT_TO_ACP_STACKALLOC(lpAppName, lpAppNameAnsi);
  5768. GODOT_TO_ACP_STACKALLOC(lpKeyName, lpKeyNameAnsi);
  5769. GODOT_TO_ACP_STACKALLOC(lpDefault, lpDefaultAnsi);
  5770. if((!lpAppNameAnsi && lpAppName) ||
  5771. (!lpKeyNameAnsi && lpKeyName) ||
  5772. (!lpDefaultAnsi && lpDefault))
  5773. return(0);
  5774. RetVal=GetPrivateProfileStringA(lpAppNameAnsi,
  5775. lpKeyNameAnsi,
  5776. lpDefaultAnsi,
  5777. lpszRet,
  5778. nSize,
  5779. lpFileNameAnsi);
  5780. if(RetVal)
  5781. MultiByteToWideChar(g_acp, 0, lpszRet, -1, lpReturnedString, nSize);
  5782. else if(lpReturnedString)
  5783. {
  5784. *lpReturnedString = '\0';
  5785. }
  5786. // Finished
  5787. return RetVal;
  5788. }
  5789. End=
  5790. [EFunc]
  5791. TemplateName=GetProcAddress
  5792. Begin=
  5793. FARPROC __stdcall
  5794. GodotGetProcAddress(HMODULE hModule, LPCSTR lpProcName)
  5795. {
  5796. // We do not wrap this function to convert strings; we wrap it because
  5797. // we need to work around the InitMultipleMonitorStubs code in multimon.h
  5798. // which has its own little delayload implementation built in.
  5799. if((GetUserHandle() == hModule) &&
  5800. (strcmp(lpProcName, "GetMonitorInfoW") == 0))
  5801. {
  5802. return((FARPROC)&GodotGetMonitorInfoW);
  5803. }
  5804. return(GetProcAddress(hModule, lpProcName));
  5805. }
  5806. End=
  5807. [EFunc]
  5808. TemplateName=GetProfileSectionW
  5809. Begin=
  5810. DWORD __stdcall
  5811. GodotGetProfileSectionW(LPCWSTR lpAppName, LPWSTR lpReturnedString, DWORD nSize)
  5812. {
  5813. // Begin locals
  5814. DWORD RetVal;
  5815. LPSTR lpAppNameAnsi;
  5816. LPSTR lpReturnedStringAnsi;
  5817. _STACKALLOC((nSize*g_mcs)+1, lpReturnedStringAnsi);
  5818. GODOT_TO_ACP_STACKALLOC(lpAppName, lpAppNameAnsi);
  5819. if((!lpReturnedStringAnsi) ||
  5820. (lpAppName && !lpAppNameAnsi))
  5821. {
  5822. SetLastError(ERROR_STACK_OVERFLOW);
  5823. return(FALSE);
  5824. }
  5825. RetVal=GetProfileSectionA(lpAppNameAnsi, lpReturnedStringAnsi, nSize);
  5826. if(RetVal)
  5827. GrszToGrwz(lpReturnedStringAnsi, lpReturnedString, nSize);
  5828. else if(lpReturnedString)
  5829. {
  5830. *lpReturnedString = '\0';
  5831. }
  5832. // Finished
  5833. return RetVal;
  5834. }
  5835. End=
  5836. [EFunc]
  5837. TemplateName=GetProfileStringW
  5838. Begin=
  5839. DWORD __stdcall
  5840. GodotGetProfileStringW( LPCWSTR lpAppName,
  5841. LPCWSTR lpKeyName,
  5842. LPCWSTR lpDefault,
  5843. LPWSTR lpReturnedString,
  5844. DWORD nSize
  5845. )
  5846. {
  5847. // Begin locals
  5848. DWORD RetVal;
  5849. LPSTR lpAppNameAnsi, lpKeyNameAnsi, lpDefaultAnsi;
  5850. LPSTR lpReturnedStringAnsi;
  5851. _STACKALLOC((nSize*g_mcs)+1, lpReturnedStringAnsi);
  5852. if(!lpReturnedStringAnsi)
  5853. {
  5854. SetLastError(ERROR_STACK_OVERFLOW);
  5855. return(0);
  5856. }
  5857. GODOT_TO_ACP_STACKALLOC(lpAppName, lpAppNameAnsi);
  5858. GODOT_TO_ACP_STACKALLOC(lpKeyName, lpKeyNameAnsi);
  5859. GODOT_TO_ACP_STACKALLOC(lpDefault, lpDefaultAnsi);
  5860. if((!lpAppNameAnsi && lpAppName) ||
  5861. (!lpKeyNameAnsi && lpKeyName) ||
  5862. (!lpDefaultAnsi && lpDefault))
  5863. return(0);
  5864. ZeroMemory(lpReturnedStringAnsi, (nSize*g_mcs)+1);
  5865. RetVal=GetProfileStringA(lpAppNameAnsi, lpKeyNameAnsi, lpDefaultAnsi, lpReturnedStringAnsi, nSize);
  5866. if(RetVal)
  5867. MultiByteToWideChar(g_acp, 0, lpReturnedStringAnsi, -1, lpReturnedString, nSize);
  5868. else if(lpReturnedString)
  5869. {
  5870. *lpReturnedString = '\0';
  5871. }
  5872. // Finished
  5873. return RetVal;
  5874. }
  5875. End=
  5876. [EFunc]
  5877. TemplateName=GetPropA
  5878. Begin=
  5879. HANDLE __stdcall
  5880. GodotGetPropA(HWND hWnd, LPCSTR lpString)
  5881. {
  5882. if(IsInternalWindowProperty((LPWSTR)lpString, FALSE))
  5883. return(FALSE);
  5884. return(GetPropA(hWnd, lpString));
  5885. }
  5886. End=
  5887. [EFunc]
  5888. TemplateName=GetPropW
  5889. Begin=
  5890. HANDLE __stdcall
  5891. GodotGetPropW( HWND hWnd, LPCWSTR lpString)
  5892. {
  5893. LPSTR lpStringAnsi;
  5894. if(IsInternalWindowProperty(lpString, TRUE))
  5895. return(FALSE);
  5896. GODOT_TO_ACP_STACKALLOC(lpString, lpStringAnsi);
  5897. if(!lpStringAnsi && lpString)
  5898. return(0);
  5899. return(GetPropA(hWnd, lpStringAnsi));
  5900. }
  5901. End=
  5902. [EFunc]
  5903. TemplateName=GetRoleTextW
  5904. Begin=
  5905. UINT __stdcall GodotGetRoleTextW(DWORD lRole, LPWSTR lpszRole, UINT cchRoleMax)
  5906. {
  5907. UINT RetVal = 0;
  5908. if (s_pfnGetRoleTextA == NULL)
  5909. {
  5910. // Must allocate stuff for this API call
  5911. s_pfnGetRoleTextA = (PFNrgta)GetOleAccProc("GetRoleTextA");
  5912. }
  5913. if (s_pfnGetRoleTextA)
  5914. {
  5915. if(lpszRole==NULL || cchRoleMax==0)
  5916. {
  5917. RetVal = (s_pfnGetRoleTextA(lRole, (LPSTR)NULL, 0));
  5918. }
  5919. else
  5920. {
  5921. LPSTR lpszRoleAnsi = GodotHeapAlloc(cchRoleMax * g_mcs);
  5922. if(lpszRoleAnsi==NULL)
  5923. {
  5924. SetLastError(ERROR_OUTOFMEMORY);
  5925. return(0);
  5926. }
  5927. RetVal = (s_pfnGetRoleTextA(lRole, lpszRoleAnsi, cchRoleMax));
  5928. if(RetVal)
  5929. {
  5930. MultiByteToWideChar(g_acp, 0, lpszRoleAnsi, RetVal + 1, lpszRole, cchRoleMax);
  5931. RetVal = gwcslen(lpszRole);
  5932. }
  5933. GodotHeapFree(lpszRoleAnsi);
  5934. }
  5935. }
  5936. else
  5937. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  5938. return RetVal;
  5939. }
  5940. End=
  5941. [EFunc]
  5942. TemplateName=GetSaveFileNameW
  5943. Begin=
  5944. BOOL __stdcall
  5945. GodotGetSaveFileNameW(LPOPENFILENAMEW lpofn)
  5946. {
  5947. return(GetOpenSaveFileHelper(lpofn, FALSE));
  5948. }
  5949. End=
  5950. [EFunc]
  5951. TemplateName=GetSaveFileNamePreviewW
  5952. Begin=
  5953. BOOL __stdcall GodotGetSaveFileNamePreviewW(LPOPENFILENAMEW lpofn)
  5954. {
  5955. // ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
  5956. return(FALSE);
  5957. }
  5958. End=
  5959. [EFunc]
  5960. TemplateName=GetShortPathNameW
  5961. Begin=
  5962. DWORD __stdcall
  5963. GodotGetShortPathNameW(LPCWSTR lpszLongPath, LPWSTR lpszShortPath, DWORD cchBuffer)
  5964. {
  5965. // Begin locals
  5966. DWORD RetVal;
  5967. LPSTR lpszLongPathAnsi;
  5968. LPSTR lpszShortPathAnsi;
  5969. UINT cpg = FILES_CPG;
  5970. _STACKALLOC((cchBuffer*g_mcs)+1, lpszShortPathAnsi);
  5971. GODOT_TO_CPG_STACKALLOC(lpszLongPath, lpszLongPathAnsi, cpg, g_mcs);
  5972. RetVal=GetShortPathNameA(lpszLongPathAnsi, lpszShortPathAnsi, cchBuffer);
  5973. if(RetVal)
  5974. MultiByteToWideChar(g_acp, 0, lpszShortPathAnsi, -1, lpszShortPath, cchBuffer);
  5975. // Finished
  5976. return RetVal;
  5977. }
  5978. End=
  5979. [EFunc]
  5980. TemplateName=GetStartupInfoW
  5981. Begin=
  5982. void __stdcall
  5983. GodotGetStartupInfoW(LPSTARTUPINFOW lpsiW)
  5984. {
  5985. // Begin locals
  5986. STARTUPINFOA siA;
  5987. ZeroMemory(&siA, sizeof(STARTUPINFOA));
  5988. siA.lpReserved = 0;
  5989. siA.cb = sizeof(STARTUPINFOA);
  5990. // Call the 'A' version of the API
  5991. GetStartupInfoA(&siA);
  5992. // Begin postcall
  5993. lpsiW->cb = sizeof(STARTUPINFOW);
  5994. lpsiW->lpReserved = NULL;
  5995. lpsiW->dwX = siA.dwX;
  5996. lpsiW->dwY = siA.dwY;
  5997. lpsiW->dwXSize = siA.dwXSize;
  5998. lpsiW->dwYSize = siA.dwYSize;
  5999. lpsiW->dwXCountChars = siA.dwXCountChars;
  6000. lpsiW->dwYCountChars = siA.dwYCountChars;
  6001. lpsiW->dwFillAttribute = siA.dwFillAttribute;
  6002. lpsiW->dwFlags = siA.dwFlags;
  6003. lpsiW->wShowWindow = siA.wShowWindow;
  6004. lpsiW->cbReserved2 = siA.cbReserved2;
  6005. lpsiW->lpReserved2 = siA.lpReserved2;
  6006. lpsiW->hStdInput = siA.hStdInput;
  6007. lpsiW->hStdOutput = siA.hStdOutput;
  6008. lpsiW->hStdError = siA.hStdError;
  6009. // For the strings, we have to use our static buffers.
  6010. // The OS returns actual pointers to the process startup
  6011. // info, which we cannot do because that info is ANSI!
  6012. if(FSTRING_VALID(siA.lpDesktop))
  6013. {
  6014. MultiByteToWideChar(g_acp, 0, siA.lpDesktop, -1, m_wzDesktop, 256);
  6015. lpsiW->lpDesktop = m_wzDesktop;
  6016. }
  6017. if(FSTRING_VALID(siA.lpTitle))
  6018. {
  6019. MultiByteToWideChar(g_acp, 0, siA.lpTitle, -1, m_wzTitle, 256);
  6020. lpsiW->lpTitle = m_wzTitle;
  6021. }
  6022. return;
  6023. }
  6024. End=
  6025. [EFunc]
  6026. TemplateName=GetStateTextW
  6027. Begin=
  6028. UINT __stdcall GodotGetStateTextW(DWORD lStateBit, LPWSTR lpszState, UINT cchState)
  6029. {
  6030. UINT RetVal = 0;
  6031. if (s_pfnGetStateTextA == NULL)
  6032. {
  6033. // Must allocate stuff for this API call
  6034. s_pfnGetStateTextA = (PFNgsta)GetOleAccProc("GetStateTextA");
  6035. }
  6036. if (s_pfnGetStateTextA)
  6037. {
  6038. if(lpszState==NULL)
  6039. {
  6040. RetVal = (s_pfnGetStateTextA(lStateBit, (LPSTR)lpszState, cchState));
  6041. }
  6042. else
  6043. {
  6044. LPSTR lpszStateAnsi = GodotHeapAlloc(cchState * g_mcs);
  6045. if(lpszStateAnsi==NULL)
  6046. {
  6047. SetLastError(ERROR_OUTOFMEMORY);
  6048. return(0);
  6049. }
  6050. RetVal = (s_pfnGetStateTextA(lStateBit, lpszStateAnsi, cchState));
  6051. if(RetVal)
  6052. {
  6053. MultiByteToWideChar(g_acp, 0, lpszStateAnsi, RetVal + 1, lpszState, cchState);
  6054. RetVal = gwcslen(lpszState);
  6055. }
  6056. GodotHeapFree(lpszStateAnsi);
  6057. }
  6058. }
  6059. else
  6060. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  6061. return RetVal;
  6062. }
  6063. End=
  6064. [EFunc]
  6065. TemplateName=GetStringTypeW
  6066. Begin=
  6067. BOOL __stdcall
  6068. GodotGetStringTypeW(DWORD dwInfoType, LPWSTR lpSrcStr, int cchSrc, LPWORD lpCharType)
  6069. {
  6070. // Note that we insert a LOCALE_SYSTEM_DEFAULT Locale as the "W"
  6071. // version does not have the Locale param. After all, we want to
  6072. // look like NT does, not have just a Unicode wrapper around
  6073. // the Win9x function, which would be compatible with nothing.
  6074. LCID Locale = LOCALE_SYSTEM_DEFAULT;
  6075. UINT cpg = CpgFromLocale(Locale);
  6076. UINT mcs = CbPerChOfCpg(cpg);
  6077. LPSTR lpSrcStrAnsi;
  6078. // Begin precall
  6079. GODOT_TO_CPG_STACKALLOC(lpSrcStr, lpSrcStrAnsi, cpg, mcs);
  6080. if(!lpSrcStrAnsi && lpSrcStr)
  6081. return(FALSE);
  6082. return(GetStringTypeA(Locale, dwInfoType, lpSrcStrAnsi, cchSrc, lpCharType));
  6083. }
  6084. End=
  6085. [EFunc]
  6086. TemplateName=GetSystemDirectoryW
  6087. Begin=
  6088. UINT __stdcall
  6089. GodotGetSystemDirectoryW(LPWSTR lpBuffer, UINT uSize)
  6090. {
  6091. // Begin locals
  6092. UINT RetVal;
  6093. LPSTR lpBufferAnsi;
  6094. _STACKALLOC((uSize*g_mcs)+1, lpBufferAnsi);
  6095. if(lpBufferAnsi==NULL)
  6096. {
  6097. return(0);
  6098. }
  6099. // Call the 'A' version of the API
  6100. RetVal=GetSystemDirectoryA(lpBufferAnsi, uSize);
  6101. // Begin postcall
  6102. if(RetVal)
  6103. MultiByteToWideChar(g_acp, 0, lpBufferAnsi, -1, lpBuffer, uSize);
  6104. // Finished
  6105. return RetVal;
  6106. }
  6107. End=
  6108. [EFunc]
  6109. TemplateName=GetSystemWindowsDirectoryW
  6110. Begin=
  6111. UINT __stdcall
  6112. GodotGetSystemWindowsDirectoryW(LPWSTR lpBuffer, UINT uSize)
  6113. {
  6114. // Begin locals
  6115. UINT RetVal;
  6116. LPSTR lpBufferAnsi;
  6117. _STACKALLOC((uSize*g_mcs)+1, lpBufferAnsi);
  6118. if(lpBufferAnsi==NULL)
  6119. {
  6120. return(0);
  6121. }
  6122. // Call the 'A' version of the API. Note that there IS no
  6123. // GetSystemWindowsDirectory on Win9x. But since on a
  6124. // single user system it is the same as the old
  6125. // GetWindowsDirectory call, we can cheat very effectively.
  6126. RetVal=GetWindowsDirectoryA(lpBufferAnsi, uSize);
  6127. // Begin postcall
  6128. if(RetVal)
  6129. MultiByteToWideChar(g_acp, 0, lpBufferAnsi, -1, lpBuffer, uSize);
  6130. // Finished
  6131. return RetVal;
  6132. }
  6133. End=
  6134. [EFunc]
  6135. TemplateName=GetTempFileNameW
  6136. Begin=
  6137. UINT __stdcall
  6138. GodotGetTempFileNameW(LPCWSTR lpPathName, LPCWSTR lpPrefixString, UINT uUnique, LPWSTR lpTempFileName)
  6139. {
  6140. // Begin locals
  6141. UINT RetVal;
  6142. LPSTR lpPathNameAnsi;
  6143. LPSTR lpPrefixStringAnsi;
  6144. char lpTempFileNameAnsi[MAX_PATH + 1];
  6145. UINT cpg = FILES_CPG;
  6146. // Begin precall
  6147. GODOT_TO_CPG_STACKALLOC(lpPathName, lpPathNameAnsi, cpg, g_mcs);
  6148. GODOT_TO_CPG_STACKALLOC(lpPrefixString, lpPrefixStringAnsi, cpg, g_mcs);
  6149. RetVal=GetTempFileNameA(lpPathNameAnsi, lpPrefixStringAnsi, uUnique, lpTempFileNameAnsi);
  6150. if(RetVal)
  6151. MultiByteToWideChar(cpg, 0, lpTempFileNameAnsi, MAX_PATH, lpTempFileName, MAX_PATH);
  6152. // Finished
  6153. return RetVal;
  6154. }
  6155. End=
  6156. [EFunc]
  6157. TemplateName=GetTempPathW
  6158. Begin=
  6159. DWORD __stdcall
  6160. GodotGetTempPathW(DWORD nBufferLength, LPWSTR lpBuffer)
  6161. {
  6162. DWORD RetVal;
  6163. if(nBufferLength > MAX_PATH || !FSTRING_VALID(lpBuffer))
  6164. {
  6165. SetLastError(ERROR_INVALID_PARAMETER);
  6166. RetVal = 0;
  6167. }
  6168. else
  6169. {
  6170. char lpBufferAnsi[MAX_PATH + 1];
  6171. // Call the 'A' version of the API
  6172. RetVal=GetTempPathA(nBufferLength, lpBufferAnsi);
  6173. // Begin postcall
  6174. if(RetVal)
  6175. MultiByteToWideChar(FILES_CPG, 0, lpBufferAnsi, MAX_PATH, lpBuffer, MAX_PATH);
  6176. }
  6177. // Finished
  6178. return RetVal;
  6179. }
  6180. End=
  6181. [EFunc]
  6182. TemplateName=GetTextExtentExPointW
  6183. Begin=
  6184. BOOL __stdcall
  6185. GodotGetTextExtentExPointW(HDC hdc, LPCWSTR lpString, int cchString, int nMaxExtent,
  6186. LPINT lpnFit, LPINT alpDx, LPSIZE lpSize)
  6187. {
  6188. LPSTR lpStringAnsi;
  6189. UINT cpg = CpgFromHdc(hdc);
  6190. UINT mcs = CbPerChOfCpg(cpg);
  6191. GODOT_TO_CPG_STACKALLOC(lpString, lpStringAnsi, cpg, mcs);
  6192. if(lpStringAnsi==NULL)
  6193. {
  6194. return(FALSE);
  6195. }
  6196. return(GetTextExtentExPointA(hdc, lpStringAnsi, cchString, nMaxExtent, lpnFit, alpDx, lpSize));
  6197. }
  6198. End=
  6199. [EFunc]
  6200. TemplateName=GetTextExtentPoint32W
  6201. Begin=
  6202. BOOL __stdcall
  6203. GodotGetTextExtentPoint32W(HDC hdc, LPCWSTR lpString, int cbString, LPSIZE lpSize)
  6204. {
  6205. // Begin locals
  6206. BOOL RetVal;
  6207. LPSTR lpStringAnsi;
  6208. size_t lpStringLength;
  6209. UINT cpg = CpgFromHdc(hdc);
  6210. UINT mcs = CbPerChOfCpg(cpg);
  6211. LPWSTR lpStringCopy;
  6212. LPWSTR lpwchT;
  6213. LPWSTR lpwchEnd;
  6214. BOOL fDefault;
  6215. lpStringCopy = GodotHeapAlloc((cbString + 1) * sizeof(WCHAR));
  6216. if(lpStringCopy==NULL)
  6217. {
  6218. SetLastError(ERROR_OUTOFMEMORY);
  6219. return(FALSE);
  6220. }
  6221. lpwchT = lpStringCopy;
  6222. lpwchEnd = lpStringCopy + cbString;
  6223. // make a copy so we can muck with it
  6224. memcpy(lpStringCopy, lpString, cbString * sizeof(WCHAR));
  6225. lpStringCopy[cbString] = L'\0';
  6226. // This is a workaround for Win95 bug which causes U+00B7 character to
  6227. // be rendered improperly when using the wide API (substituting U+2219
  6228. // achieves the desired effect for some reason!)
  6229. // Note: nobuyah suggested in an MSO code review that this might be a
  6230. // perf issue?
  6231. while (lpwchT < lpwchEnd)
  6232. {
  6233. if (*lpwchT == 0x00b7)
  6234. *lpwchT = 0x2219;
  6235. lpwchT++;
  6236. }
  6237. if (FDBCS_CPG(cpg))
  6238. {
  6239. fDefault = FALSE;
  6240. if (FSTRING_VALID(lpStringCopy))
  6241. {
  6242. lpStringLength = gwcslen(lpStringCopy)+1;
  6243. _STACKALLOC(lpStringLength*mcs, lpStringAnsi);
  6244. if(lpStringAnsi==NULL)
  6245. {
  6246. GodotHeapFree(lpStringCopy);
  6247. return(FALSE);
  6248. }
  6249. WideCharToMultiByte(cpg,
  6250. WC_DEFAULTCHAR|WC_COMPOSITECHECK, // default char handling
  6251. lpStringCopy,
  6252. lpStringLength,
  6253. lpStringAnsi,
  6254. lpStringLength*mcs,
  6255. NULL,
  6256. &fDefault);
  6257. }
  6258. else
  6259. lpStringAnsi = (LPSTR)lpStringCopy;
  6260. if (fDefault)
  6261. {
  6262. // GetTextExtentPoint32W() GPFs on Win 95 FE for chars above U+00FF
  6263. // Instead use a sum of GetCharWidthW() calls, plus the difference
  6264. // between GetCharWidthW() of 'X' and GetTextExtentPoint32W of 'X'
  6265. // when we detect this case. (Stole this logic from MSO).
  6266. WCHAR wchX = L'X';
  6267. int dxp;
  6268. int dxpX;
  6269. int dxpT;
  6270. RetVal = GetTextExtentPoint32W(hdc, &wchX, 1, lpSize);
  6271. if (RetVal)
  6272. {
  6273. GodotGetCharWidthW(hdc, 'X', 'X', &dxpX);
  6274. for (dxp = 0, lpwchT = lpStringCopy; lpwchT < lpwchEnd; ++lpwchT)
  6275. {
  6276. GodotGetCharWidthW(hdc, *lpwchT, *lpwchT, &dxpT);
  6277. dxp += dxpT;
  6278. }
  6279. lpSize->cx = lpSize->cx - dxpX + dxp;
  6280. }
  6281. }
  6282. else
  6283. {
  6284. // Call the 'A' version of the API
  6285. RetVal=GetTextExtentPoint32A(hdc, lpStringAnsi, cbString, lpSize);
  6286. }
  6287. }
  6288. else
  6289. {
  6290. // Call the 'W' version of the API
  6291. RetVal=GetTextExtentPoint32W(hdc, lpStringCopy, cbString, lpSize);
  6292. }
  6293. // Finished
  6294. GodotHeapFree(lpStringCopy);
  6295. return RetVal;
  6296. }
  6297. End=
  6298. [EFunc]
  6299. TemplateName=GetTextExtentPointW
  6300. Begin=
  6301. BOOL __stdcall
  6302. GodotGetTextExtentPointW(HDC hdc, LPCWSTR lpString, int cbString, LPSIZE lpSize)
  6303. {
  6304. LPSTR lpStringAnsi;
  6305. UINT cpg;
  6306. UINT mcs;
  6307. cpg = CpgFromHdc(hdc);
  6308. mcs = CbPerChOfCpg(cpg);
  6309. GODOT_TO_CPG_STACKALLOC(lpString, lpStringAnsi, cpg, mcs);
  6310. if(lpStringAnsi==NULL)
  6311. {
  6312. return(FALSE);
  6313. }
  6314. return(GetTextExtentPointA(hdc, lpStringAnsi, cbString, lpSize));
  6315. }
  6316. End=
  6317. [EFunc]
  6318. TemplateName=GetTextFaceW
  6319. Begin=
  6320. int __stdcall
  6321. GodotGetTextFaceW(HDC hdc, int nCount, LPWSTR lpFaceName)
  6322. {
  6323. // Begin locals
  6324. int RetVal;
  6325. LPSTR lpFaceNameAnsi;
  6326. _STACKALLOC((nCount*g_mcs)+1, lpFaceNameAnsi);
  6327. if(lpFaceNameAnsi==NULL)
  6328. {
  6329. return(0);
  6330. }
  6331. // Call the 'A' version of the API
  6332. RetVal=GetTextFaceA(hdc, nCount, lpFaceNameAnsi);
  6333. // Begin postcall
  6334. if(RetVal)
  6335. MultiByteToWideChar(g_acp, 0, lpFaceNameAnsi, -1, lpFaceName, nCount);
  6336. // Finished
  6337. return RetVal;
  6338. }
  6339. End=
  6340. [EFunc]
  6341. TemplateName=GetTextMetricsW
  6342. Begin=
  6343. BOOL __stdcall
  6344. GodotGetTextMetricsW(HDC hdc, LPTEXTMETRICW lptm)
  6345. {
  6346. // Begin locals
  6347. BOOL RetVal;
  6348. TEXTMETRICA tma;
  6349. ZeroMemory(&tma, sizeof(TEXTMETRICA));
  6350. RetVal=GetTextMetricsA(hdc, &tma);
  6351. // Begin postcall
  6352. if(RetVal)
  6353. TextMetricWfromA(lptm, &tma);
  6354. // Finished
  6355. return RetVal;
  6356. }
  6357. End=
  6358. [EFunc]
  6359. TemplateName=GetTimeFormatW
  6360. Begin=
  6361. int __stdcall
  6362. GodotGetTimeFormatW( LCID Locale,
  6363. DWORD dwFlags,
  6364. const SYSTEMTIME * lpTime,
  6365. LPCWSTR lpFormat,
  6366. LPWSTR lpTimeStr,
  6367. int cchTime
  6368. )
  6369. {
  6370. // Begin locals
  6371. int RetVal;
  6372. LPSTR lpFormatAnsi;
  6373. UINT cpg;
  6374. UINT mcs;
  6375. // Begin precall
  6376. if(dwFlags & LOCALE_USE_CP_ACP)
  6377. {
  6378. cpg = g_acp;
  6379. mcs = g_mcs;
  6380. }
  6381. else
  6382. {
  6383. cpg = CpgFromLocale(Locale);
  6384. mcs = CbPerChOfCpg(cpg);
  6385. }
  6386. GODOT_TO_CPG_STACKALLOC(lpFormat, lpFormatAnsi, cpg, mcs);
  6387. if (FSTRING_VALID(lpTimeStr) && (cchTime > 0))
  6388. {
  6389. LPSTR lpTimeStrAnsi;
  6390. _STACKALLOC((cchTime*mcs)+1, lpTimeStrAnsi);
  6391. ZeroMemory(lpTimeStrAnsi, (cchTime*mcs)+1);
  6392. RetVal=GetTimeFormatA(Locale, dwFlags, lpTime, lpFormatAnsi, lpTimeStrAnsi, ((cchTime+1)*mcs));
  6393. if(RetVal)
  6394. MultiByteToWideChar(cpg, 0, lpTimeStrAnsi, cchTime*mcs, lpTimeStr, cchTime);
  6395. }
  6396. else
  6397. RetVal=GetTimeFormatA(Locale, dwFlags, lpTime, lpFormatAnsi, NULL, cchTime);
  6398. if ((RetVal == 0) && lpTimeStr && 0 < cchTime)
  6399. *lpTimeStr = L'\0';
  6400. return RetVal;
  6401. }
  6402. End=
  6403. [EFunc]
  6404. TemplateName=GetUserNameW
  6405. Begin=
  6406. BOOL __stdcall
  6407. GodotGetUserNameW(LPWSTR lpBuffer, LPDWORD nSize)
  6408. {
  6409. // Begin locals
  6410. BOOL RetVal;
  6411. LPSTR lpBufferAnsi;
  6412. if(!nSize)
  6413. {
  6414. SetLastError(ERROR_INVALID_PARAMETER);
  6415. return(FALSE);
  6416. }
  6417. _STACKALLOC((*nSize * g_mcs) + 1, lpBufferAnsi);
  6418. if(lpBufferAnsi==NULL)
  6419. {
  6420. SetLastError(ERROR_STACK_OVERFLOW);
  6421. return(0);
  6422. }
  6423. ZeroMemory(lpBufferAnsi, (*nSize * g_mcs) + 1);
  6424. // Call the 'A' version of the API
  6425. RetVal=GetUserNameA(lpBufferAnsi, nSize);
  6426. // Begin postcall
  6427. if(RetVal && lpBuffer && nSize)
  6428. MultiByteToWideChar(g_acp, 0, lpBufferAnsi, -1, lpBuffer, *(nSize));
  6429. // nSize has TCHARs, which should be okay for the buffer here
  6430. // Finished
  6431. return RetVal;
  6432. }
  6433. End=
  6434. [EFunc]
  6435. TemplateName=GetVersionExW
  6436. Begin=
  6437. BOOL __stdcall
  6438. GodotGetVersionExW(LPOSVERSIONINFOW lpVersionInformation)
  6439. {
  6440. // Begin locals
  6441. BOOL RetVal;
  6442. // Note that even if they pass a OSVERSIONINFOEXW structure, we are
  6443. // only going with the the old OSVERSIONINFO part, since the other
  6444. // stuff is not supported on Win9x
  6445. if(lpVersionInformation->dwOSVersionInfoSize < sizeof(OSVERSIONINFOW))
  6446. {
  6447. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  6448. return(FALSE);
  6449. }
  6450. else
  6451. {
  6452. OSVERSIONINFOA osvia;
  6453. ZeroMemory(&osvia, sizeof(OSVERSIONINFOA));
  6454. osvia.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
  6455. RetVal=GetVersionExA(&osvia);
  6456. // Begin postcall
  6457. if(RetVal)
  6458. {
  6459. memcpy(lpVersionInformation, &osvia, (5*sizeof(DWORD)));
  6460. MultiByteToWideChar(g_acp, 0, osvia.szCSDVersion, -1, lpVersionInformation->szCSDVersion, 128);
  6461. }
  6462. // Finished
  6463. return RetVal;
  6464. }
  6465. }
  6466. End=
  6467. [EFunc]
  6468. TemplateName=GetVolumeInformationW
  6469. Begin=
  6470. BOOL __stdcall
  6471. GodotGetVolumeInformationW( LPCWSTR lpRootPathName,
  6472. LPWSTR lpVolumeNameBuffer,
  6473. DWORD nVolumeNameSize,
  6474. LPDWORD lpVolumeSerialNumber,
  6475. LPDWORD lpMaximumComponentLength,
  6476. LPDWORD lpFileSystemFlags,
  6477. LPWSTR lpFileSystemNameBuffer,
  6478. DWORD nFileSystemNameSize
  6479. )
  6480. {
  6481. // Begin locals
  6482. BOOL RetVal;
  6483. LPSTR lpRootPathNameAnsi;
  6484. LPSTR lpVolumeNameBufferAnsi;
  6485. DWORD cbVolumeNameBuffer;
  6486. LPSTR lpFileSystemNameBufferAnsi;
  6487. DWORD cbFileSystemNameBuffer;
  6488. // Begin precall
  6489. GODOT_TO_ACP_STACKALLOC(lpRootPathName, lpRootPathNameAnsi);
  6490. if((lpVolumeNameBuffer && (nVolumeNameSize > 0)))
  6491. {
  6492. cbVolumeNameBuffer = (nVolumeNameSize*g_mcs)+1;
  6493. _STACKALLOC(cbVolumeNameBuffer, lpVolumeNameBufferAnsi);
  6494. }
  6495. else
  6496. {
  6497. cbVolumeNameBuffer = 0;
  6498. lpVolumeNameBufferAnsi = NULL;
  6499. }
  6500. if((lpFileSystemNameBuffer && (nFileSystemNameSize > 0)))
  6501. {
  6502. cbFileSystemNameBuffer = (nFileSystemNameSize*g_mcs)+1;
  6503. _STACKALLOC(cbFileSystemNameBuffer, lpFileSystemNameBufferAnsi);
  6504. }
  6505. else
  6506. {
  6507. cbFileSystemNameBuffer = 0;
  6508. lpFileSystemNameBufferAnsi = NULL;
  6509. }
  6510. // Call the 'A' version of the API
  6511. RetVal=GetVolumeInformationA( lpRootPathNameAnsi,
  6512. lpVolumeNameBufferAnsi,
  6513. cbVolumeNameBuffer,
  6514. lpVolumeSerialNumber,
  6515. lpMaximumComponentLength,
  6516. lpFileSystemFlags,
  6517. lpFileSystemNameBufferAnsi,
  6518. cbFileSystemNameBuffer
  6519. );
  6520. // Begin postcall
  6521. if(RetVal)
  6522. {
  6523. if(lpVolumeNameBufferAnsi && lpVolumeNameBuffer && nVolumeNameSize)
  6524. MultiByteToWideChar(g_acp, 0,
  6525. lpVolumeNameBufferAnsi, -1,
  6526. lpVolumeNameBuffer, nVolumeNameSize);
  6527. if(lpFileSystemNameBufferAnsi && lpFileSystemNameBuffer && nFileSystemNameSize)
  6528. MultiByteToWideChar(g_acp, 0,
  6529. lpFileSystemNameBufferAnsi, -1,
  6530. lpFileSystemNameBuffer, nFileSystemNameSize);
  6531. }
  6532. else
  6533. {
  6534. if (lpVolumeNameBuffer && (0 < nVolumeNameSize))
  6535. *lpVolumeNameBuffer = L'\0';
  6536. if (lpFileSystemNameBuffer && (0 < nFileSystemNameSize))
  6537. *lpFileSystemNameBuffer = L'\0';
  6538. }
  6539. // Finished
  6540. return RetVal;
  6541. }
  6542. End=
  6543. [EFunc]
  6544. TemplateName=GetWindowLongA
  6545. Begin=
  6546. LONG __stdcall
  6547. GodotGetWindowLongA(HWND hWnd, int nIndex)
  6548. {
  6549. return(GetWindowLongInternal(hWnd, nIndex, FALSE));
  6550. }
  6551. End=
  6552. [EFunc]
  6553. TemplateName=GetWindowLongW
  6554. Begin=
  6555. LONG __stdcall
  6556. GodotGetWindowLongW(HWND hWnd, int nIndex)
  6557. {
  6558. return(GetWindowLongInternal(hWnd, nIndex, TRUE));
  6559. }
  6560. End=
  6561. [EFunc]
  6562. TemplateName=GetWindowModuleFileNameW
  6563. Begin=
  6564. UINT __stdcall
  6565. GodotGetWindowModuleFileNameW(HWND hwnd, LPWSTR pszFileName, UINT cchFileNameMax)
  6566. {
  6567. // Begin locals
  6568. UINT RetVal = 0;
  6569. if (s_pfnGetWindowModuleFileNameA == NULL)
  6570. {
  6571. // Must allocate stuff for this API call
  6572. s_pfnGetWindowModuleFileNameA = (PFNgwmfna)GetUserProc("GetWindowModuleFileNameA");
  6573. }
  6574. if (s_pfnGetWindowModuleFileNameA)
  6575. {
  6576. LPSTR pszFileNameAnsi;
  6577. _STACKALLOC((cchFileNameMax*g_mcs)+1, pszFileNameAnsi);
  6578. if(pszFileNameAnsi==NULL)
  6579. {
  6580. return(0);
  6581. }
  6582. RetVal = (s_pfnGetWindowModuleFileNameA(hwnd, pszFileNameAnsi, cchFileNameMax));
  6583. // Begin postcall
  6584. if(RetVal)
  6585. MultiByteToWideChar(g_acp, 0, pszFileNameAnsi, -1, pszFileName, cchFileNameMax);
  6586. }
  6587. else
  6588. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  6589. // Finished
  6590. return RetVal;
  6591. }
  6592. End=
  6593. [EFunc]
  6594. TemplateName=GetWindowsDirectoryW
  6595. Begin=
  6596. UINT __stdcall
  6597. GodotGetWindowsDirectoryW(LPWSTR lpBuffer, UINT uSize)
  6598. {
  6599. // Begin locals
  6600. UINT RetVal;
  6601. LPSTR lpBufferAnsi;
  6602. _STACKALLOC((uSize*g_mcs)+1, lpBufferAnsi);
  6603. if(lpBufferAnsi==NULL)
  6604. {
  6605. return(0);
  6606. }
  6607. // Call the 'A' version of the API
  6608. RetVal=GetWindowsDirectoryA(lpBufferAnsi, uSize);
  6609. // Begin postcall
  6610. if(RetVal && lpBuffer && uSize)
  6611. MultiByteToWideChar(g_acp, 0, lpBufferAnsi, -1, lpBuffer, uSize);
  6612. // Finished
  6613. return RetVal;
  6614. }
  6615. End=
  6616. [EFunc]
  6617. TemplateName=GetWindowTextW
  6618. Begin=
  6619. int __stdcall
  6620. GodotGetWindowTextW(HWND hWnd, LPWSTR lpString, int nMaxCount)
  6621. {
  6622. /******* Blackbox Testing results for GetWindowText Win32 API ******
  6623. (information taken from VSANSI layer comments)
  6624. TestCase lpString nMaxCount Return Value *lpString modified
  6625. ======================================================================
  6626. Testing GetWindowTextW on WinNT :-
  6627. A !NULL 0 0 No
  6628. B NULL 0 0 No
  6629. C NULL !0 0 No
  6630. D !NULL !0 cch w/o \0 Yes
  6631. Testing GetWindowTextA on Win95 :-
  6632. A !NULL 0 0 Yes
  6633. B NULL 0 GPF!!
  6634. C NULL !0 GPF!!
  6635. D !NULL !0 cch w/o \0 Yes
  6636. *********************************************************************/
  6637. if(!(lpString && nMaxCount > 0))
  6638. {
  6639. // If they did not pass a buffer, then we take no chances.
  6640. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  6641. return(0);
  6642. }
  6643. else
  6644. {
  6645. int RetVal;
  6646. LPSTR lpStringAnsi;
  6647. lpStringAnsi = GodotHeapAlloc((nMaxCount*g_mcs)+1);
  6648. if(lpStringAnsi==NULL)
  6649. {
  6650. return(0);
  6651. }
  6652. ZeroMemory(lpStringAnsi, (nMaxCount*g_mcs)+1);
  6653. RetVal=GetWindowTextA(hWnd, lpStringAnsi, nMaxCount);
  6654. if(RetVal)
  6655. {
  6656. MultiByteToWideChar(g_acp, 0, lpStringAnsi, -1, lpString, nMaxCount);
  6657. RetVal = gwcslen(lpString);
  6658. lpString[nMaxCount - 1] = L'\0';
  6659. }
  6660. else
  6661. {
  6662. // On some Win9x platforms (i.e. Millenium) they will still return 0
  6663. // if the buffer is not large enough, even though PSDK docs claim
  6664. // they will just truncate. Lets mimic the NT behavior.
  6665. if((GetLastError() == ERROR_INSUFFICIENT_BUFFER) && (lpStringAnsi) && (*lpStringAnsi))
  6666. {
  6667. MultiByteToWideChar(g_acp, 0, lpStringAnsi, -1, lpString, nMaxCount);
  6668. RetVal = gwcslen(lpString);
  6669. }
  6670. else if(lpString)
  6671. {
  6672. // GetWindowText() returns 0 when you call it on a window which
  6673. // has no text (e.g. edit control without any text). It also initializes
  6674. // the buffer passed in to receive the text to "\0". So we should initialize
  6675. // the buffer passed in before returning.
  6676. *lpString = L'\0';
  6677. }
  6678. }
  6679. GodotHeapFree(lpStringAnsi);
  6680. return RetVal;
  6681. }
  6682. }
  6683. End=
  6684. [EFunc]
  6685. TemplateName=GetWindowTextLengthW
  6686. Begin=
  6687. int __stdcall GodotGetWindowTextLengthW(HWND hWnd)
  6688. {
  6689. int RetVal;
  6690. RetVal=GetWindowTextLengthA(hWnd);
  6691. // Note that on DBCS Win9x, this number can be up
  6692. // to twice what the window actually contains.
  6693. if((RetVal != 0) && FDBCS_CPG(g_acp))
  6694. {
  6695. __try
  6696. {
  6697. int nMaxCountAnsi = RetVal + 1;
  6698. LPSTR lpStringAnsi;
  6699. // They might have a whole MB of text here, so lets call the
  6700. // safe version of the macro
  6701. lpStringAnsi = _alloca(nMaxCountAnsi);
  6702. // Note that we do *not* call GodotGetWindowTextW, as
  6703. // this would force an additional stack alloc on us.
  6704. if(GetWindowTextA(hWnd, lpStringAnsi, nMaxCountAnsi) > 0)
  6705. {
  6706. int nMaxCount = (RetVal + 1) * sizeof(WCHAR);
  6707. LPWSTR lpString;
  6708. lpString = _alloca(nMaxCount);
  6709. return(MultiByteToWideChar(g_acp, 0, lpStringAnsi, -1, lpString, nMaxCount));
  6710. }
  6711. }
  6712. __except( EXCEPTION_EXECUTE_HANDLER )
  6713. {
  6714. gresetstkoflw();
  6715. // We failed here; no biggee, we already picked up an
  6716. // answer from the original call.
  6717. }
  6718. // If GetWindowTextA failed we will let the retval
  6719. // stand, as we are no worse off than before.
  6720. return(RetVal);
  6721. }
  6722. return(RetVal);
  6723. }
  6724. End=
  6725. [EFunc]
  6726. TemplateName=GlobalGetAtomNameW
  6727. Begin=
  6728. UINT __stdcall
  6729. GodotGlobalGetAtomNameW(ATOM nAtom, LPWSTR lpBuffer, int nSize)
  6730. {
  6731. // Begin locals
  6732. UINT RetVal;
  6733. LPSTR lpBufferAnsi;
  6734. _STACKALLOC((nSize*g_mcs)+1, lpBufferAnsi);
  6735. if(lpBufferAnsi==NULL)
  6736. {
  6737. return(0);
  6738. }
  6739. // Call the 'A' version of the API
  6740. RetVal=GlobalGetAtomNameA(nAtom, lpBufferAnsi, nSize);
  6741. // Begin postcall
  6742. if(RetVal)
  6743. MultiByteToWideChar(g_acp, 0, lpBufferAnsi, -1, lpBuffer, nSize);
  6744. // Finished
  6745. return RetVal;
  6746. }
  6747. End=
  6748. [EFunc]
  6749. TemplateName=GrayStringW
  6750. Begin=
  6751. BOOL __stdcall
  6752. GodotGrayStringW( HDC hDC,
  6753. HBRUSH hBrush,
  6754. GRAYSTRINGPROC lpOutputFunc,
  6755. LPARAM lpData,
  6756. int nCount,
  6757. int X,
  6758. int Y,
  6759. int nWidth,
  6760. int nHeight
  6761. )
  6762. {
  6763. LPGODOTTLSINFO lpgti;
  6764. LPARAM lpDataAnsi;
  6765. BOOL RetVal;
  6766. UINT cpg = CpgFromHdc(hDC);
  6767. UINT mcs = CbPerChOfCpg(cpg);
  6768. if((lpOutputFunc == NULL) && ((void *)lpData == NULL))
  6769. {
  6770. // We must have at least one of these!
  6771. SetLastError(ERROR_INVALID_PARAMETER);
  6772. return(FALSE);
  6773. }
  6774. else if(lpOutputFunc == NULL)
  6775. {
  6776. // No callback, so this is easy: one convert and off to the "A" version.
  6777. GODOT_TO_CPG_STACKALLOC(lpData, lpDataAnsi, cpg, mcs);
  6778. return(GrayStringA(hDC, hBrush, lpOutputFunc, lpDataAnsi, nCount, X, Y, nWidth, nHeight));
  6779. }
  6780. else
  6781. {
  6782. // They have a callback, so we have to use it.
  6783. if(!(lpgti = GetThreadInfoSafe(TRUE)))
  6784. {
  6785. SetLastError(ERROR_OUTOFMEMORY);
  6786. return(FALSE);
  6787. }
  6788. if((lpgti->pfnGrayString &&
  6789. (lpgti->pfnGrayString != lpOutputFunc)) ||
  6790. lpgti->cGrayString >= GODOTMAXREFCOUNT)
  6791. {
  6792. // A hook is already defined
  6793. SetLastError(ERROR_INVALID_FILTER_PROC);
  6794. return(FALSE);
  6795. }
  6796. lpgti->pfnGrayString = lpOutputFunc;
  6797. lpgti->cpgGrayString = cpg;
  6798. lpgti->cGrayString++;
  6799. RetVal = GrayStringA(hDC, hBrush, &GrayStringProc, lpData, nCount, X, Y, nWidth, nHeight);
  6800. lpgti->cGrayString--;
  6801. lpgti->pfnGrayString = NULL;
  6802. return(RetVal);
  6803. }
  6804. }
  6805. End=
  6806. [EFunc]
  6807. TemplateName=InitializeSecurityContextW
  6808. Begin=
  6809. SECURITY_STATUS __stdcall
  6810. GodotInitializeSecurityContextW( PCredHandle phCredential,
  6811. PCtxtHandle phContext,
  6812. SEC_WCHAR SEC_FAR * pTargetName,
  6813. unsigned long int fContextReq,
  6814. unsigned long int Reserved1,
  6815. unsigned long int TargetDataRep,
  6816. PSecBufferDesc pInput,
  6817. unsigned long int Reserved2,
  6818. PCtxtHandle phNewContext,
  6819. PSecBufferDesc pOutput,
  6820. unsigned long int * pfContextAttr,
  6821. PTimeStamp ptsExpiry
  6822. )
  6823. {
  6824. // ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
  6825. return(SEC_E_UNSUPPORTED_FUNCTION);
  6826. }
  6827. End=
  6828. [EFunc]
  6829. TemplateName=InitSecurityInterfaceW
  6830. Begin=
  6831. PSecurityFunctionTableW __stdcall GodotInitSecurityInterfaceW(void)
  6832. {
  6833. // ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
  6834. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  6835. return(NULL);
  6836. }
  6837. End=
  6838. [EFunc]
  6839. TemplateName=InsertMenuItemW
  6840. Begin=
  6841. BOOL __stdcall
  6842. GodotInsertMenuItemW(HMENU hMenu, UINT uItem, BOOL fByPosition, LPCMENUITEMINFOW lpmiiw)
  6843. {
  6844. // Begin locals
  6845. BOOL RetVal;
  6846. MENUITEMINFOA miia;
  6847. BOOL fAlloc = MenuItemInfoAfromW(&miia, lpmiiw);
  6848. RetVal=InsertMenuItemA(hMenu, uItem, fByPosition, &miia);
  6849. if(fAlloc)
  6850. GodotHeapFree(miia.dwTypeData);
  6851. // Finished
  6852. return RetVal;
  6853. }
  6854. End=
  6855. [EFunc]
  6856. TemplateName=IsBadStringPtrW
  6857. Begin=
  6858. BOOL __stdcall
  6859. GodotIsBadStringPtrW(LPCWSTR lpwz, UINT_PTR cchMax)
  6860. {
  6861. if(cchMax > 0)
  6862. {
  6863. if(lpwz == NULL)
  6864. return(TRUE);
  6865. else
  6866. {
  6867. // The function is documented as checking the smaller of the number
  6868. // of bytes covered by the specified NULL terminated UNICODE string,
  6869. // or the number of WCHARs specified by cchMax. Note that cchMax may
  6870. // be -1 (meaning "go to the string's end") but that's ok because
  6871. // the loop down below will look for the terminator.
  6872. LPCWSTR lpwzStart = lpwz;
  6873. LPCWSTR lpwzEnd = &lpwzStart[cchMax - 1];
  6874. WCHAR wch = L'\0';
  6875. _try
  6876. {
  6877. do
  6878. {
  6879. wch = *(volatile WCHAR *)lpwzStart;
  6880. lpwzStart++;
  6881. }
  6882. // back up one for the string check since we have
  6883. // already advanced.
  6884. while(wch && ((lpwzStart - 1) != lpwzEnd));
  6885. }
  6886. _except(EXCEPTION_EXECUTE_HANDLER)
  6887. {
  6888. //if(GetExceptionCode == EXCEPTION_ACCESS_VIOLATION)
  6889. return(TRUE);
  6890. }
  6891. }
  6892. }
  6893. // if we made it here, then the string is good
  6894. return(FALSE);
  6895. }
  6896. End=
  6897. [EFunc]
  6898. TemplateName=IsCharAlphaW
  6899. Begin=
  6900. BOOL __stdcall
  6901. GodotIsCharAlphaW(WCHAR ch)
  6902. {
  6903. CHAR chAnsi[] = "\0\0";
  6904. BOOL fUsedDefault = FALSE;
  6905. if (&ch != NULL)
  6906. WideCharToMultiByte(g_acp, 0, (LPWSTR)&ch, 1, (LPSTR)&chAnsi, g_mcs, NULL, &fUsedDefault);
  6907. else
  6908. return(FALSE);
  6909. if(!fUsedDefault)
  6910. return(IsCharAlphaA(*chAnsi));
  6911. SetLastError(ERROR_INVALID_PARAMETER);
  6912. return(FALSE);
  6913. }
  6914. End=
  6915. [EFunc]
  6916. TemplateName=IsCharAlphaNumericW
  6917. Begin=
  6918. BOOL __stdcall
  6919. GodotIsCharAlphaNumericW(WCHAR ch)
  6920. {
  6921. CHAR chAnsi[] = "\0\0";
  6922. BOOL fUsedDefault = FALSE;
  6923. if (&ch != NULL)
  6924. WideCharToMultiByte(g_acp, 0, (LPWSTR)&ch, 1, (LPSTR)&chAnsi, 1, NULL, &fUsedDefault);
  6925. else
  6926. return(FALSE);
  6927. if(!fUsedDefault)
  6928. return(IsCharAlphaNumericA(*chAnsi));
  6929. SetLastError(ERROR_INVALID_PARAMETER);
  6930. return(FALSE);
  6931. }
  6932. End=
  6933. [EFunc]
  6934. TemplateName=IsCharLowerW
  6935. Begin=
  6936. BOOL __stdcall
  6937. GodotIsCharLowerW(WCHAR ch)
  6938. {
  6939. CHAR chAnsi[] = "\0\0";
  6940. BOOL fUsedDefault = FALSE;
  6941. if (&ch != NULL)
  6942. WideCharToMultiByte(g_acp, 0, (LPWSTR)&ch, 1, (LPSTR)&chAnsi, g_mcs, NULL, &fUsedDefault);
  6943. else
  6944. return(FALSE);
  6945. if(!fUsedDefault)
  6946. return(IsCharLowerA(*chAnsi));
  6947. SetLastError(ERROR_INVALID_PARAMETER);
  6948. return(FALSE);
  6949. }
  6950. End=
  6951. [EFunc]
  6952. TemplateName=IsCharUpperW
  6953. Begin=
  6954. BOOL __stdcall
  6955. GodotIsCharUpperW(WCHAR ch)
  6956. {
  6957. CHAR chAnsi[] = "\0\0";
  6958. BOOL fUsedDefault = FALSE;
  6959. if (&ch != NULL)
  6960. WideCharToMultiByte(g_acp, 0, (LPWSTR)&ch, 1, (LPSTR)&chAnsi, g_mcs, NULL, &fUsedDefault);
  6961. else
  6962. return(FALSE);
  6963. if(!fUsedDefault)
  6964. return(IsCharUpperA(*chAnsi));
  6965. SetLastError(ERROR_INVALID_PARAMETER);
  6966. return(FALSE);
  6967. }
  6968. End=
  6969. [EFunc]
  6970. TemplateName=IsClipboardFormatAvailable
  6971. Begin=
  6972. BOOL __stdcall
  6973. GodotIsClipboardFormatAvailable(UINT format)
  6974. {
  6975. BOOL RetVal = IsClipboardFormatAvailable(format);
  6976. if(!RetVal)
  6977. {
  6978. // The API failed, lets find out if our more
  6979. // intelligent opinion differs from theirs.
  6980. if(format==CF_UNICODETEXT)
  6981. {
  6982. // CF_UNICODETEXT is legal if it will take CF_TEXT
  6983. RetVal = IsClipboardFormatAvailable(CF_TEXT);
  6984. }
  6985. else if((format==CF_TEXT) || (format==CF_OEMTEXT))
  6986. {
  6987. // CF_TEXT is legal if it will take CF_UNICODETEXT
  6988. RetVal = IsClipboardFormatAvailable(CF_UNICODETEXT);
  6989. }
  6990. }
  6991. return(RetVal);
  6992. }
  6993. End=
  6994. [EFunc]
  6995. TemplateName=IsDestinationReachableW
  6996. Begin=
  6997. BOOL __stdcall
  6998. GodotIsDestinationReachableW(LPCWSTR lpszDestination, LPQOCINFO lpQOCInfo)
  6999. {
  7000. if (s_pfnIsDestinationReachableA == NULL)
  7001. {
  7002. // Must allocate stuff for this API call
  7003. s_pfnIsDestinationReachableA = (pfnIDRA)GetSensApiProc("IsDestinationReachableA");
  7004. }
  7005. if (s_pfnIsDestinationReachableA)
  7006. {
  7007. LPSTR lpszDestinationAnsi;
  7008. GODOT_TO_ACP_STACKALLOC(lpszDestination, lpszDestinationAnsi);
  7009. if(!lpszDestinationAnsi && lpszDestination)
  7010. return(FALSE);
  7011. return(s_pfnIsDestinationReachableA(lpszDestinationAnsi, lpQOCInfo));
  7012. }
  7013. else
  7014. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  7015. return(FALSE);
  7016. }
  7017. End=
  7018. [EFunc]
  7019. TemplateName=IsTextUnicode
  7020. Begin=
  7021. BOOL __stdcall
  7022. GodotIsTextUnicode(void * lpBuffer, int cb, LPINT lpi)
  7023. {
  7024. // We need this API for our own usage, so we may as
  7025. // well give it to users as well.
  7026. return(RtlIsTextUnicode(lpBuffer, cb, (PULONG)lpi));
  7027. }
  7028. End=
  7029. [EFunc]
  7030. TemplateName=IsValidCodePage
  7031. Begin=
  7032. // IsValidCodePage is wrapped for UTF-7/UTF-8 support
  7033. BOOL __stdcall
  7034. GodotIsValidCodePage(UINT CodePage)
  7035. {
  7036. // Return success for these code pages
  7037. if ((CodePage == CP_UTF7) || (CodePage == CP_UTF8))
  7038. return (TRUE);
  7039. // Return TRUE if the DLL is there
  7040. if (CodePage == CP_GB18030)
  7041. return(0 != GetGB18030Handle());
  7042. return(IsValidCodePage(CodePage));
  7043. }
  7044. End=
  7045. [EFunc]
  7046. TemplateName=IsWindowUnicode
  7047. Begin=
  7048. // IsWindowUnicode wrapped since the windows we create are kinda Unicode, right? :-)
  7049. BOOL __stdcall
  7050. GodotIsWindowUnicode(HWND hWnd)
  7051. {
  7052. if (IsWindow(hWnd))
  7053. return(GetUnicodeWindowProp(hWnd));
  7054. // Not a valid window. We cannot live with the GetLastError set by
  7055. // IsWindow (ERROR_INVALID_ADDRESS) since IsWindowUnicode does
  7056. // something different
  7057. SetLastError(ERROR_INVALID_WINDOW_HANDLE);
  7058. return FALSE; // IsWindowUnicode(hWnd);
  7059. }
  7060. End=
  7061. [EFunc]
  7062. TemplateName=IsDialogMessageW
  7063. Begin=
  7064. BOOL __stdcall
  7065. GodotIsDialogMessageW(HWND hDlg, LPMSG lpMsg)
  7066. {
  7067. return((BOOL)GodotDispatchMessage(mtIsDialogMessage, hDlg, 0, lpMsg));
  7068. }
  7069. End=
  7070. [EFunc]
  7071. TemplateName=joyGetDevCapsW
  7072. Begin=
  7073. MMRESULT __stdcall GodotjoyGetDevCapsW(UINT_PTR uJoyID, LPJOYCAPSW pjc, UINT cbjc)
  7074. {
  7075. // UNSUPPORTED FUNCTION: Documented as a failure stub
  7076. if(cbjc < sizeof(JOYCAPSW))
  7077. {
  7078. return(MMSYSERR_INVALPARAM);
  7079. }
  7080. else
  7081. {
  7082. JOYCAPSA jcA;
  7083. MMRESULT RetVal;
  7084. ZeroMemory(&jcA, sizeof(JOYCAPSA));
  7085. RetVal = joyGetDevCapsA(uJoyID, &jcA, sizeof(JOYCAPSA));
  7086. if(RetVal == MMSYSERR_NOERROR)
  7087. {
  7088. pjc->wMid = jcA.wMid;
  7089. pjc->wPid = jcA.wPid;
  7090. pjc->wXmin = jcA.wXmin;
  7091. pjc->wXmax = jcA.wXmax;
  7092. pjc->wYmin = jcA.wYmin;
  7093. pjc->wYmax = jcA.wYmax;
  7094. pjc->wZmin = jcA.wZmin;
  7095. pjc->wZmax = jcA.wZmax;
  7096. pjc->wNumButtons = jcA.wNumButtons;
  7097. pjc->wPeriodMin = jcA.wPeriodMin;
  7098. pjc->wPeriodMax = jcA.wPeriodMax;
  7099. pjc->wRmin = jcA.wRmin;
  7100. pjc->wRmax = jcA.wRmax;
  7101. pjc->wRmin = jcA.wRmin;
  7102. pjc->wUmin = jcA.wUmin;
  7103. pjc->wUmax = jcA.wUmax;
  7104. pjc->wVmin = jcA.wVmin;
  7105. pjc->wVmax = jcA.wVmax;
  7106. pjc->wCaps = jcA.wCaps;
  7107. pjc->wMaxAxes = jcA.wMaxAxes;
  7108. pjc->wNumAxes = jcA.wNumAxes;
  7109. pjc->wMaxButtons = jcA.wMaxButtons;
  7110. MultiByteToWideChar(g_acp, 0, jcA.szPname, MAXPNAMELEN, pjc->szPname, MAXPNAMELEN);
  7111. MultiByteToWideChar(g_acp, 0, jcA.szRegKey, MAXPNAMELEN, pjc->szRegKey, MAXPNAMELEN);
  7112. MultiByteToWideChar(g_acp, 0,
  7113. jcA.szOEMVxD, MAX_JOYSTICKOEMVXDNAME,
  7114. pjc->szOEMVxD, MAX_JOYSTICKOEMVXDNAME);
  7115. }
  7116. return(RetVal);
  7117. }
  7118. }
  7119. End=
  7120. [EFunc]
  7121. TemplateName=LCMapStringW
  7122. Begin=
  7123. int __stdcall
  7124. GodotLCMapStringW( LCID Locale,
  7125. DWORD dwMapFlags,
  7126. LPCWSTR lpSrcStr,
  7127. int cchSrc,
  7128. LPWSTR lpDestStr,
  7129. int cchDest
  7130. )
  7131. {
  7132. // Begin locals
  7133. int RetVal;
  7134. LPSTR lpSrcStrAnsi;
  7135. UINT cpg;
  7136. UINT mcs;
  7137. // a small head check for flags that are not supported
  7138. if (dwMapFlags & (LCMAP_SIMPLIFIED_CHINESE | LCMAP_TRADITIONAL_CHINESE | LCMAP_BYTEREV))
  7139. {
  7140. SetLastError(ERROR_INVALID_PARAMETER);
  7141. return(0);
  7142. }
  7143. // Begin precall: LOCALE_USE_CP_ACP is *not* adding a feature!
  7144. if (dwMapFlags & LOCALE_USE_CP_ACP)
  7145. cpg = g_acp;
  7146. else
  7147. cpg = CpgFromLocale(Locale);
  7148. mcs = CbPerChOfCpg(cpg);
  7149. if (FSTRING_VALID(lpSrcStr))
  7150. {
  7151. if(cchSrc==-1)
  7152. {
  7153. _STACKALLOC(gwcslen(lpSrcStr) * mcs, lpSrcStrAnsi);
  7154. }
  7155. else
  7156. {
  7157. _STACKALLOC(cchSrc * mcs, lpSrcStrAnsi);
  7158. }
  7159. if(lpSrcStr && lpSrcStrAnsi)
  7160. WideCharToMultiByte(cpg, 0, lpSrcStr, cchSrc, lpSrcStrAnsi, cchSrc*mcs, NULL, NULL);
  7161. }
  7162. else
  7163. lpSrcStrAnsi = (LPSTR)lpSrcStr;
  7164. if (!(dwMapFlags & LCMAP_SORTKEY))
  7165. {
  7166. if((cchDest > 0) && (lpDestStr != NULL))
  7167. {
  7168. // Ok, we have a buffer, so lets alloc and convert
  7169. int lpDestStrLength = cchDest*mcs;
  7170. LPSTR lpDestStrAnsi;
  7171. _STACKALLOC(lpDestStrLength, lpDestStrAnsi);
  7172. if((!lpDestStrAnsi) ||
  7173. (lpSrcStr && !lpSrcStrAnsi))
  7174. {
  7175. SetLastError(ERROR_STACK_OVERFLOW);
  7176. return(0);
  7177. }
  7178. RetVal=LCMapStringA(Locale, dwMapFlags, lpSrcStrAnsi, cchSrc, lpDestStrAnsi, lpDestStrLength);
  7179. if((RetVal !=0) && (lpDestStr != NULL))
  7180. MultiByteToWideChar(cpg, 0, lpDestStrAnsi, cchDest*mcs, lpDestStr, cchDest);
  7181. }
  7182. else
  7183. // no buffer, so just get the size. Comes back in TCHARs so this should be okay
  7184. RetVal=LCMapStringA(Locale, dwMapFlags, lpSrcStrAnsi, cchSrc, NULL, 0);
  7185. }
  7186. else
  7187. {
  7188. // Sort keys, we can go into the Unicode return buffer directly
  7189. RetVal=LCMapStringA(Locale, dwMapFlags, lpSrcStrAnsi, cchSrc, (LPSTR)lpDestStr, cchDest);
  7190. }
  7191. return RetVal;
  7192. }
  7193. End=
  7194. [EFunc]
  7195. TemplateName=LoadAcceleratorsW
  7196. Begin=
  7197. HACCEL __stdcall
  7198. GodotLoadAcceleratorsW(HINSTANCE hInstance, LPCWSTR lpTableName)
  7199. {
  7200. LPSTR lpTableNameAnsi;
  7201. GODOT_TO_ACP_STACKALLOC(lpTableName, lpTableNameAnsi);
  7202. if(!lpTableNameAnsi && lpTableName)
  7203. return(FALSE);
  7204. return(LoadAcceleratorsA(hInstance, lpTableNameAnsi));
  7205. }
  7206. End=
  7207. [EFunc]
  7208. TemplateName=LoadMenuIndirectW
  7209. Begin=
  7210. HMENU __stdcall
  7211. GodotLoadMenuIndirectW(const MENUTEMPLATEW * lpMenuTemplate)
  7212. {
  7213. return(LoadMenuIndirectA(lpMenuTemplate));
  7214. }
  7215. End=
  7216. [EFunc]
  7217. TemplateName=LoadStringW
  7218. Begin=
  7219. int __stdcall
  7220. GodotLoadStringW(HINSTANCE hInstance, UINT uID, LPWSTR lpBuffer, int nBufferMax)
  7221. {
  7222. // Code cribbed from module.c (same in NT and Win9x)
  7223. HANDLE hResInfo;
  7224. LPWSTR lpsz;
  7225. int cch;
  7226. cch = 0;
  7227. // Make sure the parms are valid.
  7228. if (!lpBuffer || (nBufferMax-- == 0))
  7229. return 0;
  7230. // String Tables are broken up into 16 string resources. Find the resource
  7231. // containing the string we are interested in.
  7232. if(hResInfo = FindResourceA(hInstance, (LPSTR)((LONG)(((USHORT)uID >> 4) + 1)), RT_STRING))
  7233. {
  7234. // Load the resource. Note LoadResource returns an address.
  7235. if(lpsz = LoadResource(hInstance, hResInfo))
  7236. {
  7237. _try
  7238. {
  7239. // Move past the other strings in this resource.
  7240. // (16 strings in a segment -> & 0x0F)
  7241. uID &= 0x0F;
  7242. while(TRUE)
  7243. {
  7244. cch = *(lpsz++); // PASCAL like string count
  7245. // first WCHAR is count of WCHARs
  7246. if (uID-- == 0) break;
  7247. lpsz += cch; // Step to start of next string
  7248. }
  7249. // Don't copy more than the max allowed.
  7250. if (cch > nBufferMax)
  7251. cch = nBufferMax;
  7252. gwcsncpy(lpBuffer, lpsz, cch);
  7253. }
  7254. _except(EXCEPTION_EXECUTE_HANDLER)
  7255. {
  7256. SetLastError( ERROR_BAD_FORMAT);
  7257. cch = 0;
  7258. }
  7259. }
  7260. }
  7261. // Append a NULL.
  7262. lpBuffer[cch] = 0;
  7263. return cch;
  7264. }
  7265. End=
  7266. [EFunc]
  7267. TemplateName=lstrcatW
  7268. Begin=
  7269. LPWSTR __stdcall
  7270. GodotlstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
  7271. {
  7272. if (FWIN95())
  7273. return gwcscat(lpString1, lpString2);
  7274. else
  7275. return(lstrcatW(lpString1, lpString2));
  7276. }
  7277. End=
  7278. [EFunc]
  7279. TemplateName=lstrcmpW
  7280. Begin=
  7281. int __stdcall
  7282. GodotlstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
  7283. {
  7284. return(CompareHelper(lpString1, lpString2, FALSE));
  7285. }
  7286. End=
  7287. [EFunc]
  7288. TemplateName=lstrcmpiW
  7289. Begin=
  7290. int __stdcall
  7291. GodotlstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
  7292. {
  7293. return(CompareHelper(lpString1, lpString2, TRUE));
  7294. }
  7295. End=
  7296. [EFunc]
  7297. TemplateName=lstrcpyW
  7298. Begin=
  7299. LPWSTR __stdcall
  7300. GodotlstrcpyW(LPWSTR lpString1, LPCWSTR lpString2)
  7301. {
  7302. if (FWIN95())
  7303. return gwcscpy(lpString1, lpString2);
  7304. else
  7305. return(lstrcpyW(lpString1, lpString2));
  7306. }
  7307. End=
  7308. [EFunc]
  7309. TemplateName=lstrcpynW
  7310. Begin=
  7311. LPWSTR __stdcall
  7312. GodotlstrcpynW(LPWSTR lpString1, LPCWSTR lpString2, int iMaxLength)
  7313. {
  7314. LPWSTR pszReturn = gwcsncpy(lpString1, lpString2, iMaxLength);
  7315. // gwcsncpy and lstrcpy behave differently about terminating NULL
  7316. // characters. The last char in the lstrcpyn buffer always gets
  7317. // a TEXT('\0'), whereas gwcsncpy doesn't do this. Thus we must
  7318. // NULL the last char before returning (gleaned from VSANSI)
  7319. lpString1[iMaxLength-1] = TEXT('\0');
  7320. return pszReturn;
  7321. }
  7322. End=
  7323. [EFunc]
  7324. TemplateName=lstrlenW
  7325. Begin=
  7326. int __stdcall
  7327. GodotlstrlenW(LPCWSTR lpString)
  7328. {
  7329. // CONSIDER: Maybe we do not need this function? Isn't it supported
  7330. // in the Unicode version on all platforms?
  7331. return gwcslen(lpString);
  7332. }
  7333. End=
  7334. [EFunc]
  7335. TemplateName=MapVirtualKeyW
  7336. Begin=
  7337. UINT __stdcall
  7338. GodotMapVirtualKeyW(UINT uCode, UINT uMapType)
  7339. {
  7340. UINT RetVal;
  7341. RetVal=MapVirtualKeyA(uCode, uMapType);
  7342. if((uMapType == 2) && (RetVal != 0))
  7343. {
  7344. // RetVal is an unshifted character in the loword, as
  7345. // well as a possible diacritic in the hiword
  7346. UINT cpg = CpgFromLocale(LOWORD(GetKeyboardLayout(0)));
  7347. UINT mcs = CbPerChOfCpg(cpg);
  7348. UINT RetValT;
  7349. RetValT = RetVal;
  7350. if(!FDBCS_CPG(cpg))
  7351. {
  7352. MultiByteToWideChar(cpg, 0, (LPSTR)RetVal, 1, (LPWSTR)(LOWORD(RetValT)), 1);
  7353. if(HIWORD(RetVal))
  7354. RetValT |= (UINT)0x80000000;
  7355. }
  7356. else
  7357. {
  7358. MultiByteToWideChar(cpg, 0, (LPSTR)RetVal, 1, (LPWSTR)RetValT, 1);
  7359. }
  7360. RetVal = RetValT;
  7361. }
  7362. return(RetVal);
  7363. }
  7364. End=
  7365. [EFunc]
  7366. TemplateName=MapVirtualKeyExW
  7367. Begin=
  7368. UINT __stdcall
  7369. GodotMapVirtualKeyExW(UINT uCode, UINT uMapType, HKL dwhkl)
  7370. {
  7371. UINT RetVal;
  7372. RetVal=MapVirtualKeyExA(uCode, uMapType, dwhkl);
  7373. if((uMapType == 2) && (RetVal != 0))
  7374. {
  7375. // RetVal is an unshifted character in the loword, as
  7376. // well as a possible diacritic in the hiword
  7377. UINT cpg = CpgFromLocale(LOWORD(dwhkl));
  7378. UINT mcs = CbPerChOfCpg(cpg);
  7379. UINT RetValT;
  7380. RetValT = RetVal;
  7381. if(!FDBCS_CPG(cpg))
  7382. {
  7383. MultiByteToWideChar(cpg, 0, (LPSTR)RetVal, 1, (LPWSTR)(LOWORD(RetValT)), 1);
  7384. if(HIWORD(RetVal))
  7385. RetValT |= (UINT)0x80000000;
  7386. }
  7387. else
  7388. {
  7389. MultiByteToWideChar(cpg, 0, (LPSTR)RetVal, 1, (LPWSTR)RetValT, 1);
  7390. }
  7391. RetVal = RetValT;
  7392. }
  7393. return(RetVal);
  7394. }
  7395. End=
  7396. [EFunc]
  7397. TemplateName=mciGetDeviceIDW
  7398. Begin=
  7399. MCIDEVICEID __stdcall GodotmciGetDeviceIDW(LPCWSTR pszDevice)
  7400. {
  7401. LPSTR pszDeviceAnsi;
  7402. GODOT_TO_ACP_STACKALLOC(pszDevice, pszDeviceAnsi);
  7403. if(!pszDeviceAnsi && pszDevice)
  7404. return(0);
  7405. return(mciGetDeviceIDA(pszDeviceAnsi));
  7406. }
  7407. End=
  7408. [EFunc]
  7409. TemplateName=mciGetErrorStringW
  7410. Begin=
  7411. BOOL __stdcall GodotmciGetErrorStringW(MCIERROR mcierr, LPWSTR pszText, UINT cchText)
  7412. {
  7413. BOOL RetVal;
  7414. if(pszText==NULL || cchText == 0)
  7415. return(midiInGetErrorTextA(mcierr, (LPSTR)pszText, cchText));
  7416. else
  7417. {
  7418. if(MAXERRORLENGTH < cchText)
  7419. {
  7420. return(MMSYSERR_INVALPARAM);
  7421. }
  7422. else
  7423. {
  7424. char pszTextAnsi[MAXERRORLENGTH];
  7425. ZeroMemory(pszTextAnsi, MAXERRORLENGTH);
  7426. RetVal = mciGetErrorStringA(mcierr, pszTextAnsi, cchText);
  7427. if(RetVal)
  7428. MultiByteToWideChar(g_acp, 0, pszTextAnsi, -1, pszText, cchText);
  7429. return(RetVal);
  7430. }
  7431. }
  7432. }
  7433. End=
  7434. [EFunc]
  7435. TemplateName=mciSendCommandW
  7436. Begin=
  7437. MCIERROR __stdcall GodotmciSendCommandW(MCIDEVICEID mciId, UINT uMsg, DWORD_PTR dw1, DWORD_PTR dw2)
  7438. {
  7439. // ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
  7440. return(MCIERR_UNSUPPORTED_FUNCTION);
  7441. }
  7442. End=
  7443. [EFunc]
  7444. TemplateName=mciSendStringW
  7445. Begin=
  7446. MCIERROR __stdcall
  7447. GodotmciSendStringW(LPCWSTR lpstrCommand, LPWSTR lpstrReturnString, UINT uReturnLength, HWND hwndCallback)
  7448. {
  7449. // UNSUPPORTED FUNCTION: Documented as a failure stub
  7450. LPSTR lpstrCommandAnsi;
  7451. MCIERROR RetVal;
  7452. GODOT_TO_ACP_STACKALLOC(lpstrCommand, lpstrCommandAnsi);
  7453. if(!lpstrCommandAnsi && lpstrCommand)
  7454. return(MCIERR_OUT_OF_MEMORY);
  7455. if(lpstrReturnString && (uReturnLength > 0))
  7456. {
  7457. LPSTR lpstrReturnStringAnsi;
  7458. _STACKALLOC(uReturnLength * g_mcs, lpstrReturnStringAnsi);
  7459. if(lpstrReturnStringAnsi==NULL)
  7460. return(MCIERR_OUT_OF_MEMORY);
  7461. ZeroMemory(lpstrReturnStringAnsi, uReturnLength * g_mcs);
  7462. RetVal = mciSendStringA(lpstrCommandAnsi, lpstrReturnStringAnsi, uReturnLength, hwndCallback);
  7463. if(RetVal == MMSYSERR_NOERROR)
  7464. MultiByteToWideChar(g_acp, 0, lpstrReturnStringAnsi, -1, lpstrReturnString, uReturnLength);
  7465. else
  7466. *lpstrReturnString = L'\0';
  7467. return(RetVal);
  7468. }
  7469. else
  7470. return(mciSendStringA(lpstrCommandAnsi, NULL, 0, hwndCallback));
  7471. }
  7472. End=
  7473. [EFunc]
  7474. TemplateName=MCIWndCreateW
  7475. Begin=
  7476. HWND _cdecl GodotMCIWndCreateW(HWND hwndParent, HINSTANCE hInstance, DWORD dwStyle, LPCWSTR szFile)
  7477. {
  7478. HWND RetVal;
  7479. LPSTR szFileAnsi;
  7480. LPGODOTTLSINFO lpgti = GetThreadInfoSafe(TRUE);
  7481. if(!lpgti)
  7482. return(0);
  7483. GODOT_TO_ACP_STACKALLOC(szFile, szFileAnsi);
  7484. if(!szFileAnsi && szFile)
  7485. return(0);
  7486. INIT_WINDOW_SNIFF(lpgti->hHook);
  7487. RetVal=MCIWndCreateWA(hwndParent, hInstance, dwStyle, szFileAnsi);
  7488. TERM_WINDOW_SNIFF(lpgti->hHook);
  7489. return RetVal;
  7490. }
  7491. End=
  7492. [EFunc]
  7493. TemplateName=MessageBoxW
  7494. Begin=
  7495. int __stdcall
  7496. GodotMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType)
  7497. {
  7498. // Code taken from the BASE depot
  7499. size_t cbAnsiText, cbAnsiCaption;
  7500. int RetVal;
  7501. LPSTR pAnsiText = NULL;
  7502. LPSTR pAnsiCaption = NULL;
  7503. if(cbAnsiText = WideCharToMultiByte(g_acp, 0, lpText, -1, 0, 0, NULL, NULL))
  7504. {
  7505. if(pAnsiText = GlobalAlloc(GMEM_FIXED, cbAnsiText))
  7506. WideCharToMultiByte(g_acp, 0, lpText, -1, pAnsiText, cbAnsiText, NULL, NULL);
  7507. else
  7508. {
  7509. SetLastError(ERROR_OUTOFMEMORY);
  7510. return(0);
  7511. }
  7512. }
  7513. if(cbAnsiCaption = WideCharToMultiByte(g_acp, 0, lpCaption, -1, 0, 0, NULL, NULL))
  7514. {
  7515. if(pAnsiCaption = GlobalAlloc( GMEM_FIXED, cbAnsiCaption))
  7516. WideCharToMultiByte(g_acp, 0, lpCaption, -1, pAnsiCaption, cbAnsiCaption, NULL, NULL);
  7517. else
  7518. {
  7519. if(pAnsiText)
  7520. GlobalFree(pAnsiText);
  7521. SetLastError(ERROR_OUTOFMEMORY);
  7522. return(0);
  7523. }
  7524. }
  7525. RetVal=MessageBoxA(hWnd, pAnsiText, pAnsiCaption, uType);
  7526. if(pAnsiText)
  7527. GlobalFree(pAnsiText);
  7528. if(pAnsiCaption)
  7529. GlobalFree(pAnsiCaption);
  7530. return(RetVal);
  7531. }
  7532. End=
  7533. [EFunc]
  7534. TemplateName=MessageBoxExW
  7535. Begin=
  7536. int __stdcall
  7537. GodotMessageBoxExW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType, WORD wLanguageId)
  7538. {
  7539. // Code taken from the BASE depot
  7540. size_t cbAnsiText, cbAnsiCaption;
  7541. int RetVal;
  7542. LPSTR pAnsiText = NULL;
  7543. LPSTR pAnsiCaption = NULL;
  7544. if(cbAnsiText = WideCharToMultiByte(g_acp, 0, lpText, -1, 0, 0, NULL, NULL))
  7545. {
  7546. if(pAnsiText = GlobalAlloc(GMEM_FIXED, cbAnsiText))
  7547. WideCharToMultiByte(g_acp, 0, lpText, -1, pAnsiText, cbAnsiText, NULL, NULL);
  7548. else
  7549. {
  7550. SetLastError(ERROR_OUTOFMEMORY);
  7551. return(0);
  7552. }
  7553. }
  7554. if(cbAnsiCaption = WideCharToMultiByte(g_acp, 0, lpCaption, -1, 0, 0, NULL, NULL))
  7555. {
  7556. if(pAnsiCaption = GlobalAlloc(GMEM_FIXED, cbAnsiCaption))
  7557. WideCharToMultiByte(g_acp, 0, lpCaption, -1, pAnsiCaption, cbAnsiCaption, NULL, NULL);
  7558. else
  7559. {
  7560. if(pAnsiText)
  7561. GlobalFree(pAnsiText);
  7562. SetLastError(ERROR_OUTOFMEMORY);
  7563. return(0);
  7564. }
  7565. }
  7566. RetVal=MessageBoxExA(hWnd, pAnsiText, pAnsiCaption, uType, wLanguageId);
  7567. if(pAnsiText)
  7568. GlobalFree(pAnsiText);
  7569. if(pAnsiCaption)
  7570. GlobalFree(pAnsiCaption);
  7571. return(RetVal);
  7572. }
  7573. End=
  7574. [EFunc]
  7575. TemplateName=MessageBoxIndirectW
  7576. Begin=
  7577. int __stdcall
  7578. GodotMessageBoxIndirectW(const MSGBOXPARAMSW * lpMsgBoxParams)
  7579. {
  7580. // Begin locals
  7581. int RetVal;
  7582. MSGBOXPARAMSA mpa;
  7583. // Begin precall
  7584. ZeroMemory(&mpa, sizeof(MSGBOXPARAMSA));
  7585. mpa.cbSize = lpMsgBoxParams->cbSize;
  7586. mpa.hwndOwner = lpMsgBoxParams->hwndOwner;
  7587. mpa.hInstance = lpMsgBoxParams->hInstance;
  7588. mpa.dwStyle = lpMsgBoxParams->dwStyle;
  7589. mpa.dwContextHelpId = lpMsgBoxParams->dwContextHelpId;
  7590. mpa.dwLanguageId = lpMsgBoxParams->dwLanguageId;
  7591. mpa.lpfnMsgBoxCallback = lpMsgBoxParams->lpfnMsgBoxCallback;
  7592. GODOT_TO_ACP_STACKALLOC(lpMsgBoxParams->lpszText, mpa.lpszText);
  7593. GODOT_TO_ACP_STACKALLOC(lpMsgBoxParams->lpszCaption, mpa.lpszCaption);
  7594. GODOT_TO_ACP_STACKALLOC(lpMsgBoxParams->lpszIcon, mpa.lpszIcon);
  7595. if((!mpa.lpszText && lpMsgBoxParams->lpszText) ||
  7596. (!mpa.lpszCaption && lpMsgBoxParams->lpszCaption) ||
  7597. (!mpa.lpszIcon && lpMsgBoxParams->lpszIcon))
  7598. {
  7599. SetLastError(ERROR_STACK_OVERFLOW);
  7600. return(0);
  7601. }
  7602. // Call the 'A' version of the API
  7603. RetVal=MessageBoxIndirectA(&mpa);
  7604. // Finished
  7605. return RetVal;
  7606. }
  7607. End=
  7608. [EFunc]
  7609. TemplateName=midiInGetDevCapsW
  7610. Begin=
  7611. MMRESULT __stdcall GodotmidiInGetDevCapsW(UINT_PTR uDeviceID, LPMIDIINCAPSW pmic, UINT cbmic)
  7612. {
  7613. // UNSUPPORTED FUNCTION: Documented as a failure stub
  7614. if(cbmic < sizeof(MIDIINCAPSW))
  7615. {
  7616. return(MMSYSERR_INVALPARAM);
  7617. }
  7618. else
  7619. {
  7620. MIDIINCAPSA micA;
  7621. MMRESULT RetVal;
  7622. ZeroMemory(&micA, sizeof(MIDIINCAPSA));
  7623. RetVal = midiInGetDevCapsA(uDeviceID, &micA, sizeof(MIDIINCAPSA));
  7624. if(RetVal == MMSYSERR_NOERROR)
  7625. {
  7626. pmic->wMid = micA.wMid;
  7627. pmic->wPid = micA.wPid;
  7628. pmic->vDriverVersion = micA.vDriverVersion;
  7629. pmic->dwSupport = micA.dwSupport;
  7630. MultiByteToWideChar(g_acp, 0, micA.szPname, MAXPNAMELEN, pmic->szPname, MAXPNAMELEN);
  7631. }
  7632. return(RetVal);
  7633. }
  7634. }
  7635. End=
  7636. [EFunc]
  7637. TemplateName=midiInGetErrorTextW
  7638. Begin=
  7639. MMRESULT __stdcall GodotmidiInGetErrorTextW(MMRESULT mmrError, LPWSTR pszText, UINT cchText)
  7640. {
  7641. // UNSUPPORTED FUNCTION: Documented as a failure stub
  7642. if(pszText==NULL || cchText == 0)
  7643. return(midiInGetErrorTextA(mmrError, (LPSTR)pszText, cchText));
  7644. else
  7645. {
  7646. if(MAXERRORLENGTH < cchText)
  7647. {
  7648. return(MMSYSERR_INVALPARAM);
  7649. }
  7650. else
  7651. {
  7652. char pszTextA[MAXERRORLENGTH];
  7653. MMRESULT RetVal;
  7654. ZeroMemory(pszTextA, MAXERRORLENGTH);
  7655. RetVal = midiInGetErrorTextA(mmrError, pszTextA, cchText);
  7656. if(RetVal == MMSYSERR_NOERROR)
  7657. MultiByteToWideChar(g_acp, 0, pszTextA, -1, pszText, cchText);
  7658. return(RetVal);
  7659. }
  7660. }
  7661. }
  7662. End=
  7663. [EFunc]
  7664. TemplateName=midiOutGetDevCapsW
  7665. Begin=
  7666. MMRESULT __stdcall GodotmidiOutGetDevCapsW(UINT_PTR uDeviceID, LPMIDIOUTCAPSW pmoc, UINT cbmoc)
  7667. {
  7668. // UNSUPPORTED FUNCTION: Documented as a failure stub
  7669. if(cbmoc < sizeof(MIDIOUTCAPSW))
  7670. {
  7671. return(MMSYSERR_INVALPARAM);
  7672. }
  7673. else
  7674. {
  7675. MIDIOUTCAPSA mocA;
  7676. MMRESULT RetVal;
  7677. ZeroMemory(&mocA, sizeof(MIDIOUTCAPSA));
  7678. RetVal = midiOutGetDevCapsA(uDeviceID, &mocA, sizeof(MIDIOUTCAPSA));
  7679. if(RetVal == MMSYSERR_NOERROR)
  7680. {
  7681. pmoc->wMid = mocA.wMid;
  7682. pmoc->wPid = mocA.wPid;
  7683. pmoc->vDriverVersion = mocA.vDriverVersion;
  7684. pmoc->wTechnology = mocA.wTechnology;
  7685. pmoc->wVoices = mocA.wVoices;
  7686. pmoc->wNotes = mocA.wNotes;
  7687. pmoc->wChannelMask = mocA.wChannelMask;
  7688. pmoc->dwSupport = mocA.dwSupport;
  7689. MultiByteToWideChar(g_acp, 0, mocA.szPname, MAXPNAMELEN, pmoc->szPname, MAXPNAMELEN);
  7690. }
  7691. return(RetVal);
  7692. }
  7693. }
  7694. End=
  7695. [EFunc]
  7696. TemplateName=midiOutGetErrorTextW
  7697. Begin=
  7698. MMRESULT __stdcall GodotmidiOutGetErrorTextW(MMRESULT mmrError, LPWSTR pszText, UINT cchText)
  7699. {
  7700. // UNSUPPORTED FUNCTION: Documented as a failure stub
  7701. if(pszText==NULL || cchText == 0)
  7702. return(midiOutGetErrorTextA(mmrError, (LPSTR)pszText, cchText));
  7703. else
  7704. {
  7705. if(MAXERRORLENGTH < cchText)
  7706. {
  7707. return(MMSYSERR_INVALPARAM);
  7708. }
  7709. else
  7710. {
  7711. char pszTextA[MAXERRORLENGTH];
  7712. MMRESULT RetVal;
  7713. ZeroMemory(pszTextA, MAXERRORLENGTH);
  7714. RetVal = midiOutGetErrorTextA(mmrError, pszTextA, cchText);
  7715. if(RetVal == MMSYSERR_NOERROR)
  7716. MultiByteToWideChar(g_acp, 0, pszTextA, -1, pszText, cchText);
  7717. return(RetVal);
  7718. }
  7719. }
  7720. }
  7721. End=
  7722. [EFunc]
  7723. TemplateName=mixerGetControlDetailsW
  7724. Begin=
  7725. MMRESULT __stdcall GodotmixerGetControlDetailsW(HMIXEROBJ hmxobj, LPMIXERCONTROLDETAILS pmxcd, DWORD fdwDetails)
  7726. {
  7727. // ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
  7728. return(MMSYSERR_NOTSUPPORTED);
  7729. }
  7730. End=
  7731. [EFunc]
  7732. TemplateName=mixerGetDevCapsW
  7733. Begin=
  7734. MMRESULT __stdcall GodotmixerGetDevCapsW(UINT_PTR uMxId, LPMIXERCAPSW pmxcaps, UINT cbmxcaps)
  7735. {
  7736. // UNSUPPORTED FUNCTION: Documented as a failure stub
  7737. if(uMxId < sizeof(MIXERCAPSW))
  7738. {
  7739. return(MMSYSERR_INVALPARAM);
  7740. }
  7741. else
  7742. {
  7743. MIXERCAPSA mxcapsA;
  7744. MMRESULT RetVal;
  7745. ZeroMemory(&mxcapsA, sizeof(MIXERCAPSA));
  7746. RetVal = mixerGetDevCapsA(uMxId, &mxcapsA, sizeof(MIXERCAPSA));
  7747. if(RetVal == MMSYSERR_NOERROR)
  7748. {
  7749. pmxcaps->wMid = mxcapsA.wMid;
  7750. pmxcaps->wPid = mxcapsA.wPid;
  7751. pmxcaps->vDriverVersion = mxcapsA.vDriverVersion;
  7752. pmxcaps->fdwSupport = mxcapsA.fdwSupport;
  7753. pmxcaps->cDestinations = mxcapsA.cDestinations;
  7754. MultiByteToWideChar(g_acp, 0, mxcapsA.szPname, MAXPNAMELEN, pmxcaps->szPname, MAXPNAMELEN);
  7755. }
  7756. return(RetVal);
  7757. }
  7758. }
  7759. End=
  7760. [EFunc]
  7761. TemplateName=mixerGetLineControlsW
  7762. Begin=
  7763. MMRESULT __stdcall
  7764. GodotmixerGetLineControlsW(HMIXEROBJ hmxobj, LPMIXERLINECONTROLSW pmxlc, DWORD fdwControls)
  7765. {
  7766. // ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
  7767. return(MMSYSERR_NOTSUPPORTED);
  7768. }
  7769. End=
  7770. [EFunc]
  7771. TemplateName=mixerGetLineInfoW
  7772. Begin=
  7773. MMRESULT __stdcall GodotmixerGetLineInfoW(HMIXEROBJ hmxobj, LPMIXERLINEW pmxl, DWORD fdwInfo)
  7774. {
  7775. // ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
  7776. return(MMSYSERR_NOTSUPPORTED);
  7777. }
  7778. End=
  7779. [EFunc]
  7780. TemplateName=mmioInstallIOProcW
  7781. Begin=
  7782. LPMMIOPROC __stdcall GodotmmioInstallIOProcW(FOURCC fccIOProc, LPMMIOPROC pIOProc, DWORD dwFlags)
  7783. {
  7784. // ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
  7785. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  7786. return(NULL);
  7787. }
  7788. End=
  7789. [EFunc]
  7790. TemplateName=mmioRenameW
  7791. Begin=
  7792. MMRESULT __stdcall
  7793. GodotmmioRenameW(LPCWSTR pszFileName, LPCWSTR pszNewFileName, LPCMMIOINFO pmmioinfo, DWORD fdwRename)
  7794. {
  7795. // UNSUPPORTED FUNCTION: Documented as a failure stub
  7796. if((MAX_PATH < gwcslen(pszFileName)) ||
  7797. (MAX_PATH < gwcslen(pszNewFileName)))
  7798. {
  7799. SetLastError(ERROR_INVALID_PARAMETER);
  7800. return(0);
  7801. }
  7802. else
  7803. {
  7804. char pszFileNameAnsi[MAX_PATH + 1];
  7805. char pszNewFileNameAnsi[MAX_PATH + 1];
  7806. WideCharToMultiByte(g_acp, 0, pszFileName, -1, pszFileNameAnsi, MAX_PATH, NULL, NULL);
  7807. WideCharToMultiByte(g_acp, 0, pszNewFileName, -1, pszNewFileNameAnsi, MAX_PATH, NULL, NULL);
  7808. return(mmioRenameA(pszFileNameAnsi, pszNewFileNameAnsi, pmmioinfo, fdwRename));
  7809. }
  7810. }
  7811. End=
  7812. [EFunc]
  7813. TemplateName=mmioOpenW
  7814. Begin=
  7815. HMMIO __stdcall GodotmmioOpenW(LPWSTR pszFileName, LPMMIOINFO pmmioinfo, DWORD fdwOpen)
  7816. {
  7817. // UNSUPPORTED FUNCTION: Documented as a failure stub
  7818. if(MAX_PATH < gwcslen(pszFileName))
  7819. {
  7820. SetLastError(ERROR_INVALID_PARAMETER);
  7821. if(pmmioinfo)
  7822. pmmioinfo->wErrorRet = MMIOERR_PATHNOTFOUND;
  7823. return(0);
  7824. }
  7825. else
  7826. {
  7827. char pszFileNameAnsi[MAX_PATH + 1];
  7828. WideCharToMultiByte(g_acp, 0, pszFileName, -1, pszFileNameAnsi, MAX_PATH, NULL, NULL);
  7829. return(mmioOpenA(pszFileNameAnsi, pmmioinfo, fdwOpen));
  7830. }
  7831. }
  7832. End=
  7833. [EFunc]
  7834. TemplateName=mmioStringToFOURCCW
  7835. Begin=
  7836. FOURCC __stdcall
  7837. GodotmmioStringToFOURCCW(LPCWSTR sz, UINT uFlags)
  7838. {
  7839. // UNSUPPORTED FUNCTION: Documented as a failure stub
  7840. LPSTR szAnsi;
  7841. GODOT_TO_ACP_STACKALLOC(sz, szAnsi);
  7842. return(mmioStringToFOURCCA(szAnsi, uFlags));
  7843. }
  7844. End=
  7845. [EFunc]
  7846. TemplateName=MoveFileW
  7847. Begin=
  7848. BOOL __stdcall
  7849. GodotMoveFileW(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName)
  7850. {
  7851. if((MAX_PATH < gwcslen(lpExistingFileName)) ||
  7852. (MAX_PATH < gwcslen(lpExistingFileName)))
  7853. {
  7854. SetLastError(ERROR_INVALID_PARAMETER);
  7855. return(FALSE);
  7856. }
  7857. else
  7858. {
  7859. UINT cpg = FILES_CPG;
  7860. char lpEfnA[MAX_PATH + 1];
  7861. char lpNfnA[MAX_PATH + 1];
  7862. WideCharToMultiByte(cpg, 0, lpExistingFileName, -1, lpEfnA, MAX_PATH, NULL, NULL);
  7863. WideCharToMultiByte(cpg, 0, lpNewFileName, -1, lpNfnA, MAX_PATH, NULL, NULL);
  7864. return(MoveFileA(lpEfnA, lpNfnA));
  7865. }
  7866. }
  7867. End=
  7868. [EFunc]
  7869. TemplateName=MultiByteToWideChar
  7870. Begin=
  7871. // MultiByteToWideChar is wrapped for UTF-7/UTF-8 support
  7872. int __stdcall
  7873. GodotMultiByteToWideChar( UINT CodePage,
  7874. DWORD dwFlags,
  7875. LPCSTR lpMultiByteStr,
  7876. int cbMultiByte,
  7877. LPWSTR lpWideCharStr,
  7878. int cchWideChar
  7879. )
  7880. {
  7881. UINT cpg = ((CodePage == CP_THREAD_ACP) ? g_acp : CodePage);
  7882. // See if it's a special code page value for UTF translations.
  7883. if (cpg >= NLS_CP_ALGORITHM_RANGE)
  7884. return (UTFToUnicode(cpg, dwFlags, lpMultiByteStr, cbMultiByte, lpWideCharStr, cchWideChar));
  7885. // GB 18030 specified?
  7886. if (cpg == CP_GB18030)
  7887. return(GB18030Helper(cpg,
  7888. dwFlags | NLS_CP_MBTOWC,
  7889. (LPSTR)lpMultiByteStr,
  7890. cbMultiByte,
  7891. lpWideCharStr,
  7892. cchWideChar,
  7893. NULL));
  7894. return(MultiByteToWideChar(cpg, dwFlags, lpMultiByteStr, cbMultiByte, lpWideCharStr, cchWideChar));
  7895. }
  7896. End=
  7897. [EFunc]
  7898. TemplateName=MultinetGetConnectionPerformanceW
  7899. Begin=
  7900. DWORD __stdcall
  7901. GodotMultinetGetConnectionPerformanceW( LPNETRESOURCEW lpnrw,
  7902. LPNETCONNECTINFOSTRUCT lpNetConnectInfoStruct
  7903. )
  7904. {
  7905. NETRESOURCEA nra;
  7906. ZeroMemory(&nra, sizeof(NETRESOURCEA));
  7907. memcpy(&nra, lpnrw, (4*sizeof(DWORD)));
  7908. GODOT_TO_ACP_STACKALLOC(lpnrw->lpLocalName, nra.lpLocalName);
  7909. GODOT_TO_ACP_STACKALLOC(lpnrw->lpRemoteName, nra.lpRemoteName);
  7910. GODOT_TO_ACP_STACKALLOC(lpnrw->lpComment, nra.lpComment);
  7911. GODOT_TO_ACP_STACKALLOC(lpnrw->lpProvider, nra.lpProvider);
  7912. return(MultinetGetConnectionPerformanceA(&nra, lpNetConnectInfoStruct));
  7913. }
  7914. End=
  7915. [EFunc]
  7916. TemplateName=OemToCharW
  7917. Begin=
  7918. BOOL __stdcall
  7919. GodotOemToCharW(LPCSTR lpszSrc, LPWSTR lpszDst)
  7920. {
  7921. size_t cchSrc;
  7922. // MSDN claims this function never returns FALSE. It lies (in the
  7923. // case where the buffers are identical, for example).
  7924. if ((void *)lpszSrc == (void *)lpszDst)
  7925. {
  7926. SetLastError(ERROR_INVALID_ADDRESS);
  7927. return(FALSE);
  7928. }
  7929. // Why thunk? This function is just a CP_OEM->WCHAR converter, anyway!
  7930. // Get the number of bytes in the OEM string, Unicode string should
  7931. // never be more than that
  7932. cchSrc = lstrlenA(lpszSrc);
  7933. MultiByteToWideChar(g_oemcp, MB_PRECOMPOSED | MB_USEGLYPHCHARS, lpszSrc, cchSrc, lpszDst, cchSrc);
  7934. return(TRUE);
  7935. }
  7936. End=
  7937. [EFunc]
  7938. TemplateName=OemToCharBuffW
  7939. Begin=
  7940. BOOL __stdcall
  7941. GodotOemToCharBuffW(LPCSTR lpszSrc, LPWSTR lpszDst, DWORD cchDstLength)
  7942. {
  7943. LPSTR pTemp;
  7944. // MSDN claims this function never returns FALSE. It lies (in the
  7945. // case where the buffers are identical, for example).
  7946. if ((void *)lpszSrc == (void *)lpszDst)
  7947. {
  7948. SetLastError(ERROR_INVALID_ADDRESS);
  7949. return(FALSE);
  7950. }
  7951. // Validate the input and output pointers (taken from the actual API)
  7952. if(IsBadReadPtr(pTemp = (LPSTR)lpszSrc, cchDstLength) ||
  7953. IsBadWritePtr(pTemp = (LPSTR)lpszDst, cchDstLength))
  7954. {
  7955. SetLastError(ERROR_INVALID_PARAMETER);
  7956. return(FALSE);
  7957. }
  7958. // Why thunk? This function is just a CP_OEM->WCHAR converter, anyway!
  7959. MultiByteToWideChar(g_oemcp, 0, lpszSrc, cchDstLength, lpszDst, cchDstLength);
  7960. return(TRUE);
  7961. }
  7962. End=
  7963. [EFunc]
  7964. TemplateName=OleUIAddVerbMenuW
  7965. Begin=
  7966. BOOL __stdcall
  7967. GodotOleUIAddVerbMenuW( LPOLEOBJECT lpOleObj,
  7968. LPCWSTR lpszShortType,
  7969. HMENU hMenu,
  7970. UINT uPos,
  7971. UINT uIDVerbMin,
  7972. UINT uIDVerbMax,
  7973. BOOL bAddConvert,
  7974. UINT idConvert,
  7975. HMENU * lphMenu
  7976. )
  7977. {
  7978. // UNSUPPORTED FUNCTION: Documented as a failure stub
  7979. LPCSTR lpszShortTypeAnsi;
  7980. GODOT_TO_ACP_STACKALLOC(lpszShortType, (LPSTR)lpszShortTypeAnsi);
  7981. if(!lpszShortTypeAnsi && lpszShortType)
  7982. {
  7983. return(FALSE);
  7984. }
  7985. return(OleUIAddVerbMenuA(lpOleObj, lpszShortTypeAnsi, hMenu, uPos, uIDVerbMin,
  7986. uIDVerbMax, bAddConvert, idConvert, lphMenu));
  7987. }
  7988. End=
  7989. [EFunc]
  7990. TemplateName=OleUIBusyW
  7991. Begin=
  7992. UINT __stdcall
  7993. GodotOleUIBusyW(LPOLEUIBUSYW lpoubw)
  7994. {
  7995. // UNSUPPORTED FUNCTION: Documented as a failure stub
  7996. OLEUIBUSYA ouba;
  7997. memcpy(&ouba, lpoubw, sizeof(OLEUIBUSYA));
  7998. GODOT_TO_ACP_STACKALLOC(lpoubw->lpszCaption, ouba.lpszCaption);
  7999. GODOT_TO_ACP_STACKALLOC(lpoubw->lpszTemplate, ouba.lpszTemplate);
  8000. if((!ouba.lpszCaption && lpoubw->lpszCaption) ||
  8001. (!ouba.lpszTemplate && lpoubw->lpszTemplate))
  8002. {
  8003. SetLastError(ERROR_STACK_OVERFLOW);
  8004. return(FALSE);
  8005. }
  8006. return(OleUIBusyA(&ouba));
  8007. }
  8008. End=
  8009. [EFunc]
  8010. TemplateName=OleUIChangeIconW
  8011. Begin=
  8012. UINT __stdcall
  8013. GodotOleUIChangeIconW(LPOLEUICHANGEICONW lpouciw)
  8014. {
  8015. // UNSUPPORTED FUNCTION: Documented as a failure stub
  8016. OLEUICHANGEICONA oucia;
  8017. UINT RetVal = 0;
  8018. ALLOCRETURN arCaption;
  8019. ALLOCRETURN arTemplate;
  8020. memcpy(&oucia, lpouciw, sizeof(OLEUIBUSYA));
  8021. arCaption = GodotToAcpOnHeap(lpouciw->lpszCaption, &(LPSTR)oucia.lpszCaption);
  8022. arTemplate = GodotToAcpOnHeap(lpouciw->lpszTemplate, &(LPSTR)oucia.lpszTemplate);
  8023. if(arCaption != arFailed && arTemplate != arFailed)
  8024. {
  8025. if(oucia.dwFlags & CIF_USEICONEXE)
  8026. WideCharToMultiByte(g_acp,
  8027. 0,
  8028. lpouciw->szIconExe,
  8029. MAX_PATH,
  8030. oucia.szIconExe,
  8031. MAX_PATH,
  8032. NULL,
  8033. NULL);
  8034. RetVal = OleUIChangeIconA(&oucia);
  8035. }
  8036. else
  8037. SetLastError(ERROR_OUTOFMEMORY);
  8038. if(arCaption==arAlloc)
  8039. GodotHeapFree((LPSTR)oucia.lpszCaption);
  8040. if(arTemplate==arAlloc)
  8041. GodotHeapFree((LPSTR)oucia.lpszTemplate);
  8042. return(RetVal);
  8043. }
  8044. End=
  8045. [EFunc]
  8046. TemplateName=OleUIChangeSourceW
  8047. Begin=
  8048. UINT __stdcall
  8049. GodotOleUIChangeSourceW(LPOLEUICHANGESOURCEW _noname0)
  8050. {
  8051. // ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
  8052. return(OleUIChangeSourceW(_noname0));
  8053. }
  8054. End=
  8055. [EFunc]
  8056. TemplateName=OleUIConvertW
  8057. Begin=
  8058. UINT __stdcall
  8059. GodotOleUIConvertW(LPOLEUICONVERTW _noname0)
  8060. {
  8061. // ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
  8062. return(OleUIConvertW(_noname0));
  8063. }
  8064. End=
  8065. [EFunc]
  8066. TemplateName=OleUIEditLinksW
  8067. Begin=
  8068. UINT __stdcall
  8069. GodotOleUIEditLinksW(LPOLEUIEDITLINKSW _noname0)
  8070. {
  8071. // ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
  8072. return(OleUIEditLinksW(_noname0));
  8073. }
  8074. End=
  8075. [EFunc]
  8076. TemplateName=OleUIInsertObjectW
  8077. Begin=
  8078. UINT __stdcall
  8079. GodotOleUIInsertObjectW(LPOLEUIINSERTOBJECTW _noname0)
  8080. {
  8081. // ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
  8082. return(OleUIInsertObjectW(_noname0));
  8083. }
  8084. End=
  8085. [EFunc]
  8086. TemplateName=OleUIObjectPropertiesW
  8087. Begin=
  8088. UINT __stdcall
  8089. GodotOleUIObjectPropertiesW(LPOLEUIOBJECTPROPSW _noname0)
  8090. {
  8091. // ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
  8092. return(OleUIObjectPropertiesW(_noname0));
  8093. }
  8094. End=
  8095. [EFunc]
  8096. TemplateName=OleUIPasteSpecialW
  8097. Begin=
  8098. UINT __stdcall
  8099. GodotOleUIPasteSpecialW(LPOLEUIPASTESPECIALW _noname0)
  8100. {
  8101. // ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
  8102. return(OleUIPasteSpecialW(_noname0));
  8103. }
  8104. End=
  8105. [EFunc]
  8106. TemplateName=OleUIPromptUserW
  8107. Begin=
  8108. int _cdecl
  8109. GodotOleUIPromptUserW(int nTemplate, HWND hwndParent, ... )
  8110. {
  8111. // ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
  8112. return(OLEUI_FALSE);
  8113. }
  8114. End=
  8115. [EFunc]
  8116. TemplateName=OleUIUpdateLinksW
  8117. Begin=
  8118. BOOL __stdcall
  8119. GodotOleUIUpdateLinksW(LPOLEUILINKCONTAINERW lpOleUILinkCntr, HWND hwnd, LPWSTR lpszTitle, int cLinks)
  8120. {
  8121. // ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
  8122. return(OleUIUpdateLinksW(lpOleUILinkCntr, hwnd, lpszTitle, cLinks));
  8123. }
  8124. End=
  8125. [EFunc]
  8126. TemplateName=OpenPrinterW
  8127. Begin=
  8128. BOOL __stdcall
  8129. GodotOpenPrinterW(LPWSTR pPrinterName, LPHANDLE phPrinter, LPPRINTER_DEFAULTSW pDefault)
  8130. {
  8131. // Begin locals
  8132. BOOL RetVal = FALSE;
  8133. LPSTR pPrinterNameAnsi = NULL;
  8134. ALLOCRETURN ar = GodotToAcpOnHeap(pPrinterName, &pPrinterNameAnsi);
  8135. if(ar==arFailed)
  8136. {
  8137. SetLastError(ERROR_OUTOFMEMORY);
  8138. return(FALSE);
  8139. }
  8140. if(pDefault)
  8141. {
  8142. PRINTER_DEFAULTSA pda;
  8143. ZeroMemory(&pda, sizeof(PRINTER_DEFAULTSA));
  8144. pda.pDevMode = GodotHeapAlloc(sizeof(DEVMODEA) + pDefault->pDevMode->dmDriverExtra);
  8145. if(pda.pDevMode!=NULL)
  8146. {
  8147. ZeroMemory(pda.pDevMode, sizeof(DEVMODEA) + pDefault->pDevMode->dmDriverExtra);
  8148. DevModeAfromW(pda.pDevMode, pDefault->pDevMode);
  8149. GODOT_TO_ACP_STACKALLOC(pDefault->pDatatype, pda.pDatatype);
  8150. RetVal=OpenPrinterA(pPrinterNameAnsi, phPrinter, &pda);
  8151. GodotHeapFree(pda.pDevMode);
  8152. }
  8153. else
  8154. SetLastError(ERROR_OUTOFMEMORY);
  8155. }
  8156. else
  8157. {
  8158. RetVal=OpenPrinterA(pPrinterNameAnsi, phPrinter, NULL);
  8159. }
  8160. if(ar==arAlloc)
  8161. GodotHeapFree(pPrinterNameAnsi);
  8162. return RetVal;
  8163. }
  8164. End=
  8165. [EFunc]
  8166. TemplateName=OpenWaitableTimerW
  8167. Begin=
  8168. HANDLE __stdcall
  8169. GodotOpenWaitableTimerW(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpTimerName)
  8170. {
  8171. if (s_pfnOpenWaitableTimerA == NULL)
  8172. {
  8173. // Must allocate stuff for this API call
  8174. s_pfnOpenWaitableTimerA = (PFNowta)GetKernelProc("OpenWaitableTimerA");
  8175. }
  8176. if (s_pfnOpenWaitableTimerA)
  8177. {
  8178. LPSTR lpTimerNameAnsi;
  8179. GODOT_TO_ACP_STACKALLOC(lpTimerName, lpTimerNameAnsi);
  8180. if(!lpTimerNameAnsi && lpTimerName)
  8181. return(NULL);
  8182. return(s_pfnOpenWaitableTimerA(dwDesiredAccess, bInheritHandle, lpTimerNameAnsi));
  8183. }
  8184. else
  8185. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  8186. // Finished
  8187. return(NULL);
  8188. }
  8189. End=
  8190. [EFunc]
  8191. TemplateName=PageSetupDlgW
  8192. Begin=
  8193. BOOL __stdcall
  8194. GodotPageSetupDlgW(LPPAGESETUPDLGW lppsd)
  8195. {
  8196. // Begin locals
  8197. BOOL RetVal;
  8198. PAGESETUPDLGA psdA;
  8199. LPGODOTTLSINFO lpgti;
  8200. // If we cannot get out TLS info, then we cannot proceed
  8201. if(!(lpgti = GetThreadInfoSafe(TRUE)))
  8202. {
  8203. SetLastError(ERROR_OUTOFMEMORY);
  8204. return(0);
  8205. }
  8206. // Do the hooks now, if the user has them
  8207. if(((lpgti->pfnPagePaint) && (lppsd->Flags & PSD_ENABLEPAGEPAINTHOOK) && (lppsd->lpfnPagePaintHook)) ||
  8208. ((lpgti->pfnPageSetup) && (lppsd->Flags & PSD_ENABLEPAGESETUPHOOK) && (lppsd->lpfnPageSetupHook)))
  8209. {
  8210. SetLastError(ERROR_INVALID_FILTER_PROC);
  8211. return(0);
  8212. }
  8213. ZeroMemory(&psdA, sizeof(PAGESETUPDLGA));
  8214. psdA.lStructSize = sizeof(PAGESETUPDLGA);
  8215. if((lppsd->Flags & PSD_RETURNDEFAULT) == 0)
  8216. {
  8217. if ((lppsd->Flags & PSD_ENABLEPAGEPAINTHOOK) && (lppsd->lpfnPagePaintHook))
  8218. lpgti->pfnPagePaint = lppsd->lpfnPagePaintHook;
  8219. psdA.lpfnPagePaintHook = &PagePaintHook;
  8220. if ((lppsd->Flags & PSD_ENABLEPAGESETUPHOOK) && (lppsd->lpfnPageSetupHook))
  8221. lpgti->pfnPageSetup = lppsd->lpfnPageSetupHook;
  8222. psdA.lpfnPageSetupHook = &PageSetupHook;
  8223. }
  8224. psdA.hwndOwner = lppsd->hwndOwner;
  8225. psdA.hDevMode = HDevModeAfromW(&(lppsd->hDevMode), TRUE);
  8226. psdA.hDevNames = HDevNamesAfromW(&(lppsd->hDevNames), TRUE);
  8227. psdA.Flags = lppsd->Flags;
  8228. psdA.ptPaperSize = lppsd->ptPaperSize;
  8229. psdA.rtMinMargin = lppsd->rtMinMargin;
  8230. psdA.rtMargin = lppsd->rtMargin;
  8231. psdA.hInstance = lppsd->hInstance;
  8232. psdA.lCustData = lppsd->lCustData;
  8233. if(lppsd->Flags & PSD_ENABLEPAGESETUPTEMPLATE)
  8234. {
  8235. GODOT_TO_ACP_STACKALLOC(lppsd->lpPageSetupTemplateName, psdA.lpPageSetupTemplateName);
  8236. }
  8237. if(lppsd->Flags & PSD_ENABLEPAGESETUPTEMPLATEHANDLE)
  8238. psdA.hPageSetupTemplate = lppsd->hPageSetupTemplate;
  8239. INIT_WINDOW_SNIFF(lpgti->hHook);
  8240. RetVal=PageSetupDlgA(&psdA);
  8241. TERM_WINDOW_SNIFF(lpgti->hHook);
  8242. if((lppsd->Flags & PSD_RETURNDEFAULT) == 0)
  8243. {
  8244. if ((lppsd->Flags & PSD_ENABLEPAGEPAINTHOOK) && (lppsd->lpfnPagePaintHook))
  8245. lpgti->pfnPagePaint = NULL;
  8246. if ((lppsd->Flags & PSD_ENABLEPAGESETUPHOOK) && (lppsd->lpfnPageSetupHook))
  8247. lpgti->pfnPageSetup = NULL;
  8248. }
  8249. // Begin postcall
  8250. if(RetVal)
  8251. {
  8252. if(lppsd->hDevMode)
  8253. GlobalFree(lppsd->hDevMode);
  8254. if(lppsd->hDevNames)
  8255. GlobalFree(lppsd->hDevNames);
  8256. lppsd->hDevMode = HDevModeWfromA(&(psdA.hDevMode), TRUE);
  8257. lppsd->hDevNames = HDevNamesWfromA(&(psdA.hDevNames), TRUE);
  8258. lppsd->Flags = psdA.Flags;
  8259. lppsd->ptPaperSize = psdA.ptPaperSize;
  8260. lppsd->rtMinMargin = psdA.rtMinMargin;
  8261. lppsd->rtMargin = psdA.rtMargin;
  8262. lppsd->lCustData = psdA.lCustData;
  8263. }
  8264. // Finished
  8265. return RetVal;
  8266. }
  8267. End=
  8268. [EFunc]
  8269. TemplateName=PeekMessageW
  8270. Begin=
  8271. BOOL __stdcall
  8272. GodotPeekMessageW(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg)
  8273. {
  8274. return(GodotReceiveMessage(mtPeekMessage, lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg));
  8275. }
  8276. End=
  8277. [EFunc]
  8278. TemplateName=PlaySoundW
  8279. Begin=
  8280. BOOL __stdcall
  8281. GodotPlaySoundW(LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound)
  8282. {
  8283. BOOL RetVal;
  8284. LPSTR pszSoundAnsi;
  8285. GODOT_TO_ACP_STACKALLOC(pszSound, pszSoundAnsi);
  8286. RetVal=PlaySoundA(pszSoundAnsi, hmod, fdwSound);
  8287. return RetVal;
  8288. }
  8289. End=
  8290. [EFunc]
  8291. TemplateName=PolyTextOutW
  8292. Begin=
  8293. BOOL __stdcall
  8294. GodotPolyTextOutW(HDC hdc, const POLYTEXTW * pptxt, int cStrings)
  8295. {
  8296. POLYTEXTA * pptxta;
  8297. int i;
  8298. size_t cchMax = 0;
  8299. size_t cchT;
  8300. UINT cpg = CpgFromHdc(hdc);
  8301. UINT mcs = CbPerChOfCpg(cpg);
  8302. LPSTR lpszBuf;
  8303. BOOL RetVal;
  8304. _STACKALLOC(sizeof(POLYTEXTA)*cStrings, pptxta);
  8305. if(pptxta==NULL)
  8306. {
  8307. return(FALSE);
  8308. }
  8309. for (i = 0; i<cStrings; i++ )
  8310. {
  8311. cchT = gwcslen(pptxt[i].lpstr);
  8312. cchMax += (cchT + (cchT ? 1 : 0));
  8313. }
  8314. if(!(lpszBuf = GodotHeapAlloc(cchMax * mcs)))
  8315. {
  8316. SetLastError(ERROR_OUTOFMEMORY);
  8317. return(FALSE);
  8318. }
  8319. // Reset some vars
  8320. cchT = 0;
  8321. cchMax = 0;
  8322. ZeroMemory(pptxta, (sizeof(POLYTEXTA)*cStrings));
  8323. for (i = 0; i<cStrings; i++ )
  8324. {
  8325. pptxta[i].x = pptxt[i].x;
  8326. pptxta[i].y = pptxt[i].y;
  8327. pptxta[i].n = pptxt[i].n;
  8328. pptxta[i].uiFlags = pptxt[i].uiFlags;
  8329. pptxta[i].rcl = pptxt[i].rcl;
  8330. pptxta[i].pdx = pptxt[i].pdx;
  8331. if(FSTRING_VALID(pptxt[i].lpstr))
  8332. {
  8333. cchT = gwcslen(pptxt[i].lpstr);
  8334. pptxta[i].lpstr = (LPSTR)lpszBuf + cchMax;
  8335. WideCharToMultiByte(cpg, 0,
  8336. pptxt[i].lpstr, cchT,
  8337. (LPSTR)pptxta[i].lpstr, (cchT * mcs),
  8338. NULL, NULL);
  8339. cchMax += (cchT * mcs);
  8340. }
  8341. else
  8342. pptxta[i].lpstr = (LPSTR)pptxt[i].lpstr;
  8343. }
  8344. // Call the 'A' version of the API
  8345. RetVal = PolyTextOutA(hdc, pptxta, cStrings);
  8346. if(lpszBuf)
  8347. GodotHeapFree(lpszBuf);
  8348. return(RetVal);
  8349. }
  8350. End=
  8351. [EFunc]
  8352. TemplateName=PostMessageW
  8353. Begin=
  8354. BOOL __stdcall
  8355. GodotPostMessageW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  8356. {
  8357. return((BOOL)GodotTransmitMessage(mtPostMessage, hWnd, Msg, wParam, lParam, 0, 0, 0, 0, 0, 0));
  8358. }
  8359. End=
  8360. [EFunc]
  8361. TemplateName=PostThreadMessageW
  8362. Begin=
  8363. BOOL __stdcall
  8364. GodotPostThreadMessageW(DWORD idThread, UINT Msg, WPARAM wParam, LPARAM lParam)
  8365. {
  8366. return((BOOL)GodotTransmitMessage(mtPostThreadMessage, (HWND)idThread, Msg, wParam,
  8367. lParam, 0, 0, 0, 0, 0, 0));
  8368. }
  8369. End=
  8370. [EFunc]
  8371. TemplateName=PrintDlgW
  8372. Begin=
  8373. BOOL __stdcall
  8374. GodotPrintDlgW(LPPRINTDLGW lppd)
  8375. {
  8376. // Begin locals
  8377. BOOL RetVal;
  8378. PRINTDLGA pdA;
  8379. LPGODOTTLSINFO lpgti;
  8380. // If we cannot get out TLS info, then we cannot proceed
  8381. if(!(lpgti = GetThreadInfoSafe(TRUE)))
  8382. {
  8383. SetLastError(ERROR_OUTOFMEMORY);
  8384. return(0);
  8385. }
  8386. // Do the hooks now, if the user has them
  8387. if(((lpgti->pfnPrintDlg) && (lppd->Flags & PD_ENABLEPRINTHOOK) && (lppd->lpfnPrintHook)) ||
  8388. ((lpgti->pfnPrintDlgSetup) && (lppd->Flags & PD_ENABLESETUPHOOK) && (lppd->lpfnSetupHook)))
  8389. {
  8390. SetLastError(ERROR_INVALID_FILTER_PROC);
  8391. return(0);
  8392. }
  8393. ZeroMemory(&pdA, sizeof(PRINTDLGA));
  8394. pdA.lStructSize = sizeof(PRINTDLGA);
  8395. pdA.Flags = lppd->Flags;
  8396. if((lppd->Flags & PD_RETURNDEFAULT) == 0)
  8397. {
  8398. if ((lppd->Flags & PD_ENABLEPRINTHOOK) && (lppd->lpfnPrintHook))
  8399. lpgti->pfnPrintDlg = lppd->lpfnPrintHook;
  8400. pdA.lpfnPrintHook = &PrintHookProc;
  8401. pdA.Flags |= PD_ENABLEPRINTHOOK;
  8402. if ((lppd->Flags & PD_ENABLESETUPHOOK) && (lppd->lpfnSetupHook))
  8403. lpgti->pfnPrintDlgSetup = lppd->lpfnSetupHook;
  8404. pdA.lpfnSetupHook = &SetupHookProc;
  8405. pdA.Flags |= PD_ENABLESETUPHOOK;
  8406. }
  8407. pdA.hwndOwner = lppd->hwndOwner;
  8408. pdA.hDevMode = HDevModeAfromW(&(lppd->hDevMode), FALSE);
  8409. pdA.hDevNames = HDevNamesAfromW(&(lppd->hDevNames), FALSE);
  8410. pdA.hDC = lppd->hDC;
  8411. pdA.nFromPage = lppd->nFromPage;
  8412. pdA.nToPage = lppd->nToPage;
  8413. pdA.nMinPage = lppd->nMinPage;
  8414. pdA.nMaxPage = lppd->nMaxPage;
  8415. pdA.nCopies = lppd->nCopies;
  8416. pdA.hInstance = lppd->hInstance;
  8417. pdA.lCustData = lppd->lCustData;
  8418. if(lppd->Flags & PD_ENABLEPRINTTEMPLATE)
  8419. {
  8420. GODOT_TO_ACP_STACKALLOC(lppd->lpPrintTemplateName, pdA.lpPrintTemplateName);
  8421. }
  8422. if(lppd->Flags & PD_ENABLESETUPTEMPLATE)
  8423. {
  8424. GODOT_TO_ACP_STACKALLOC(lppd->lpSetupTemplateName, pdA.lpSetupTemplateName);
  8425. }
  8426. if(lppd->Flags & PD_ENABLEPRINTTEMPLATEHANDLE)
  8427. pdA.hPrintTemplate = lppd->hPrintTemplate;
  8428. if(lppd->Flags & PD_ENABLESETUPTEMPLATEHANDLE)
  8429. pdA.hSetupTemplate = lppd->hSetupTemplate;
  8430. INIT_WINDOW_SNIFF(lpgti->hHook);
  8431. RetVal=PrintDlgA(&pdA);
  8432. TERM_WINDOW_SNIFF(lpgti->hHook);
  8433. if((lppd->Flags & PD_RETURNDEFAULT) == 0)
  8434. {
  8435. if ((lppd->Flags & PD_ENABLEPRINTHOOK) && (lppd->lpfnPrintHook))
  8436. lpgti->pfnPrintDlg = NULL;
  8437. if ((lppd->Flags & PD_ENABLESETUPHOOK) && (lppd->lpfnSetupHook))
  8438. lpgti->pfnPrintDlgSetup = NULL;
  8439. }
  8440. // Begin postcall
  8441. if(RetVal)
  8442. {
  8443. if(lppd->hDevMode)
  8444. GlobalFree(lppd->hDevMode);
  8445. if(lppd->hDevNames)
  8446. GlobalFree(lppd->hDevNames);
  8447. lppd->hDevMode = HDevModeWfromA(&(pdA.hDevMode), TRUE);
  8448. lppd->hDevNames = HDevNamesWfromA(&(pdA.hDevNames), TRUE);
  8449. lppd->hDC = pdA.hDC;
  8450. lppd->Flags = pdA.Flags;
  8451. lppd->nFromPage = pdA.nFromPage;
  8452. lppd->nToPage = pdA.nToPage;
  8453. lppd->nMinPage = pdA.nMinPage;
  8454. lppd->nMaxPage = pdA.nMaxPage;
  8455. lppd->nCopies = pdA.nCopies;
  8456. lppd->lCustData = pdA.lCustData;
  8457. }
  8458. // Finished
  8459. return RetVal;
  8460. }
  8461. End=
  8462. [EFunc]
  8463. TemplateName=QueryContextAttributesW
  8464. Begin=
  8465. SECURITY_STATUS __stdcall
  8466. GodotQueryContextAttributesW(PCtxtHandle phContext, unsigned long int ulAttribute, void * pBuffer)
  8467. {
  8468. // ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
  8469. return(SEC_E_UNSUPPORTED_FUNCTION);
  8470. }
  8471. End=
  8472. [EFunc]
  8473. TemplateName=QueryCredentialsAttributesW
  8474. Begin=
  8475. SECURITY_STATUS __stdcall
  8476. GodotQueryCredentialsAttributesW(PCredHandle phCredential, unsigned long int ulAttribute, void * pBuffer)
  8477. {
  8478. // ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
  8479. return(SEC_E_UNSUPPORTED_FUNCTION);
  8480. }
  8481. End=
  8482. [EFunc]
  8483. TemplateName=QueryDosDeviceW
  8484. Begin=
  8485. DWORD __stdcall
  8486. GodotQueryDosDeviceW(LPCWSTR lpDeviceName, LPWSTR lpTargetPath, DWORD ucchMax)
  8487. {
  8488. DWORD RetVal;
  8489. LPSTR lpDeviceNameAnsi;
  8490. LPSTR lpTargetPathAnsi;
  8491. UINT cpg = FILES_CPG;
  8492. _STACKALLOC((ucchMax*g_mcs)+1, lpTargetPathAnsi);
  8493. GODOT_TO_CPG_STACKALLOC(lpDeviceName, lpDeviceNameAnsi, cpg, g_mcs);
  8494. RetVal=QueryDosDeviceA(lpDeviceNameAnsi, lpTargetPathAnsi, ucchMax);
  8495. if(RetVal)
  8496. MultiByteToWideChar(g_acp, 0, lpTargetPathAnsi, -1, lpTargetPath, ucchMax);
  8497. return RetVal;
  8498. }
  8499. End=
  8500. [EFunc]
  8501. TemplateName=QuerySecurityPackageInfoW
  8502. Begin=
  8503. SECURITY_STATUS __stdcall
  8504. GodotQuerySecurityPackageInfoW(SEC_WCHAR SEC_FAR * pPackageName, PSecPkgInfoW * ppPackageInfo)
  8505. {
  8506. // ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
  8507. return(SEC_E_UNSUPPORTED_FUNCTION);
  8508. }
  8509. End=
  8510. [EFunc]
  8511. TemplateName=RasConnectionNotificationW
  8512. Begin=
  8513. DWORD __stdcall
  8514. GodotRasConnectionNotificationW(HRASCONN hrasconn, HANDLE hEvent, DWORD dwFlags)
  8515. {
  8516. // if the call fails due to it not being on the OS (say like on
  8517. // win95), then it might return a "non-zero" error
  8518. // code, rather than using SetLastError. Godot will do both.
  8519. DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
  8520. if (s_pfnRasConnectionNotificationA == NULL)
  8521. s_pfnRasConnectionNotificationA = (pfnRCN)GetRasProc("RasConnectionNotificationA");
  8522. if (s_pfnRasConnectionNotificationA)
  8523. {
  8524. // Why the heck is this function A/W decorated, anyway?
  8525. // Its not like there are any strings here!
  8526. RetVal=(s_pfnRasConnectionNotificationA(hrasconn, hEvent, dwFlags));
  8527. }
  8528. else
  8529. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  8530. // Finished
  8531. return RetVal;
  8532. }
  8533. End=
  8534. [EFunc]
  8535. TemplateName=RasCreatePhonebookEntryW
  8536. Begin=
  8537. DWORD __stdcall
  8538. GodotRasCreatePhonebookEntryW(HWND hwnd, LPCWSTR lpszPhonebook)
  8539. {
  8540. // if the call fails due to it not being on the OS (say like on
  8541. // win95), then it might return a "non-zero" error
  8542. // code, rather than using SetLastError. Godot will do both.
  8543. DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
  8544. if (s_pfnRasCreatePhonebookEntryA == NULL)
  8545. s_pfnRasCreatePhonebookEntryA = (pfnRCPE)GetRasProc("RasCreatePhonebookEntryA");
  8546. if (s_pfnRasCreatePhonebookEntryA)
  8547. {
  8548. if(MAX_PATH < gwcslen(lpszPhonebook))
  8549. RetVal = ERROR_INVALID_PARAMETER;
  8550. else
  8551. {
  8552. char lpszPhonebookAnsi[MAX_PATH + 1];
  8553. WideCharToMultiByte(g_acp, 0, lpszPhonebook, -1, lpszPhonebookAnsi, MAX_PATH, NULL, NULL);
  8554. RetVal=(s_pfnRasCreatePhonebookEntryA(hwnd, lpszPhonebookAnsi));
  8555. }
  8556. }
  8557. // Finished
  8558. return(RetVal);
  8559. UNREFERENCED_PARAMETER(lpszPhonebook);
  8560. }
  8561. End=
  8562. [EFunc]
  8563. TemplateName=RasDeleteEntryW
  8564. Begin=
  8565. DWORD __stdcall
  8566. GodotRasDeleteEntryW(LPCWSTR lpszPhonebook, LPCWSTR lpszEntry)
  8567. {
  8568. // if the call fails due to it not being on the OS (say like on
  8569. // win95), then it might return a "non-zero" error
  8570. // code, rather than using SetLastError. Godot will do both.
  8571. DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
  8572. if (s_pfnRasDeleteEntryA == NULL)
  8573. s_pfnRasDeleteEntryA = (pfnRDE)GetRasProc("RasDeleteEntryA");
  8574. if (s_pfnRasDeleteEntryA)
  8575. {
  8576. if(RAS_MaxEntryName < gwcslen(lpszEntry))
  8577. RetVal = ERROR_INVALID_PARAMETER;
  8578. else
  8579. {
  8580. char lpszEntryAnsi[RAS_MaxEntryName + 1];
  8581. WideCharToMultiByte(g_acp, 0, lpszEntry, -1, lpszEntryAnsi, RAS_MaxEntryName, NULL, NULL);
  8582. RetVal=(s_pfnRasDeleteEntryA(NULL, lpszEntryAnsi));
  8583. }
  8584. }
  8585. // Finished
  8586. return RetVal;
  8587. UNREFERENCED_PARAMETER(lpszPhonebook);
  8588. }
  8589. End=
  8590. [EFunc]
  8591. TemplateName=RasDeleteSubEntryW
  8592. Begin=
  8593. DWORD __stdcall
  8594. GodotRasDeleteSubEntryW(LPCWSTR pszPhonebook, LPCWSTR pszEntry, DWORD dwSubEntryId)
  8595. {
  8596. // if the call fails due to it not being on the OS (say like on
  8597. // win95 or Win98), then it might return a "non-zero" error
  8598. // code, rather than using SetLastError. Godot will do both.
  8599. DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
  8600. if (s_pfnRasDeleteSubEntryA == NULL)
  8601. s_pfnRasDeleteSubEntryA = (pfnRDSE)GetRasProc("RasDeleteSubEntryA");
  8602. if (s_pfnRasDeleteSubEntryA)
  8603. {
  8604. CHAR pszEntryAnsi[RAS_MaxEntryName + 1];
  8605. int cch = WideCharToMultiByte(g_acp, 0, pszEntry, -1, pszEntryAnsi, RAS_MaxEntryName, NULL, NULL);
  8606. if(cch && (RAS_MaxEntryName >= cch))
  8607. RetVal=(s_pfnRasDeleteSubEntryA(NULL, pszEntryAnsi, dwSubEntryId));
  8608. else
  8609. RetVal = ERROR_INVALID_PARAMETER;
  8610. }
  8611. // Finished
  8612. return RetVal;
  8613. UNREFERENCED_PARAMETER(pszPhonebook);
  8614. }
  8615. End=
  8616. [EFunc]
  8617. TemplateName=RasDialW
  8618. Begin=
  8619. DWORD __stdcall
  8620. GodotRasDialW( LPRASDIALEXTENSIONS lpRasDialExtensions,
  8621. LPCWSTR lpszPhonebook,
  8622. LPRASDIALPARAMSW lpRasDialParams,
  8623. DWORD dwNotifierType,
  8624. LPVOID lpvNotifier,
  8625. LPHRASCONN lphRasConn
  8626. )
  8627. {
  8628. // if the call fails due to it not being on the OS (say like on
  8629. // win95), then it might return a "non-zero" error
  8630. // code, rather than using SetLastError. Godot will do both.
  8631. DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
  8632. if (s_pfnRasDialA == NULL)
  8633. s_pfnRasDialA = (pfnRD)GetRasProc("RasDialA");
  8634. if (s_pfnRasDialA)
  8635. {
  8636. // Per the PSDK, lpRasDialExtensions and
  8637. // lpszPhonebook are ignored on Win9x
  8638. RASDIALPARAMSA rdpa;
  8639. ZeroMemory(&rdpa, sizeof(RASDIALPARAMSA));
  8640. rdpa.dwSize = sizeof(RASDIALPARAMSA);
  8641. WideCharToMultiByte(g_acp, 0, lpRasDialParams->szEntryName, RAS_MaxEntryName, rdpa.szEntryName, RAS_MaxEntryName, NULL, NULL);
  8642. WideCharToMultiByte(g_acp, 0, lpRasDialParams->szPhoneNumber, RAS_MaxPhoneNumber, rdpa.szPhoneNumber, RAS_MaxPhoneNumber, NULL, NULL);
  8643. WideCharToMultiByte(g_acp, 0, lpRasDialParams->szCallbackNumber, RAS_MaxCallbackNumber, rdpa.szCallbackNumber, RAS_MaxCallbackNumber, NULL, NULL);
  8644. WideCharToMultiByte(g_acp, 0, lpRasDialParams->szUserName, UNLEN, rdpa.szUserName, UNLEN, NULL, NULL);
  8645. WideCharToMultiByte(g_acp, 0, lpRasDialParams->szPassword, PWLEN, rdpa.szPassword, PWLEN, NULL, NULL);
  8646. WideCharToMultiByte(g_acp, 0, lpRasDialParams->szDomain, DNLEN, rdpa.szDomain, RAS_MaxEntryName, NULL, NULL);
  8647. // Do not copy lprdpa->dwSubEntry or dwCallbackId, even if they are
  8648. // present, as they are Win2000 only members
  8649. RetVal=(s_pfnRasDialA(NULL, NULL, &rdpa, dwNotifierType, lpvNotifier, lphRasConn));
  8650. }
  8651. // Finished
  8652. return RetVal;
  8653. UNREFERENCED_PARAMETER(lpszPhonebook);
  8654. }
  8655. End=
  8656. [EFunc]
  8657. TemplateName=RasEditPhonebookEntryW
  8658. Begin=
  8659. DWORD __stdcall
  8660. GodotRasEditPhonebookEntryW(HWND hwnd, LPCWSTR lpszPhonebook, LPCWSTR lpszEntryName)
  8661. {
  8662. // if the call fails due to it not being on the OS (say like on
  8663. // win95), then it might return a "non-zero" error
  8664. // code, rather than using SetLastError. Godot will do both.
  8665. DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
  8666. if (s_pfnRasEditPhonebookEntryA == NULL)
  8667. s_pfnRasEditPhonebookEntryA = (pfnREPE)GetRasProc("RasEditPhonebookEntryA");
  8668. if (s_pfnRasEditPhonebookEntryA)
  8669. {
  8670. if(RAS_MaxEntryName < gwcslen(lpszEntryName))
  8671. RetVal = ERROR_INVALID_PARAMETER;
  8672. else
  8673. {
  8674. char lpszEntryNameAnsi[RAS_MaxEntryName];
  8675. WideCharToMultiByte(g_acp, 0, lpszEntryName, -1, lpszEntryNameAnsi, RAS_MaxEntryName, NULL, NULL);
  8676. RetVal=(s_pfnRasEditPhonebookEntryA(hwnd, NULL, lpszEntryNameAnsi));
  8677. }
  8678. }
  8679. // Finished
  8680. return RetVal;
  8681. UNREFERENCED_PARAMETER(lpszPhonebook);
  8682. }
  8683. End=
  8684. [EFunc]
  8685. TemplateName=RasEnumConnectionsW
  8686. Begin=
  8687. DWORD __stdcall
  8688. GodotRasEnumConnectionsW(struct tagRASCONNW * lprasconn, LPDWORD lpcb, LPDWORD lpcConnections)
  8689. {
  8690. // if the call fails due to it not being on the OS (say like on
  8691. // win95), then it might return a "non-zero" error
  8692. // code, rather than using SetLastError. Godot will do both.
  8693. DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
  8694. if (s_pfnRasEnumConnectionsA == NULL)
  8695. s_pfnRasEnumConnectionsA = (pfnREC)GetRasProc("RasEnumConnectionsA");
  8696. if (s_pfnRasEnumConnectionsA)
  8697. {
  8698. BOOL fNew;
  8699. DWORD cbConnections;
  8700. LPRASCONNA lprasconnA;
  8701. // Check parameters.
  8702. if (!lprasconn || (lprasconn->dwSize < CBRASCONNOLDW))
  8703. return ERROR_INVALID_SIZE;
  8704. if (lpcb == NULL || lpcConnections == NULL)
  8705. return ERROR_INVALID_PARAMETER;
  8706. if(fNew = (lprasconn->dwSize == CBRASCONNOLDW))
  8707. {
  8708. cbConnections = CBRASCONNOLDA * (*lpcb / CBRASCONNOLDW);
  8709. _STACKALLOC(cbConnections, lprasconnA);
  8710. ZeroMemory(lprasconnA, cbConnections);
  8711. lprasconnA->dwSize = CBRASCONNOLDA;
  8712. }
  8713. else
  8714. {
  8715. cbConnections = CBRASCONNNEWA * (*lpcb / CBRASCONNNEWW);
  8716. _STACKALLOC(cbConnections, lprasconnA);
  8717. ZeroMemory(lprasconnA, cbConnections);
  8718. lprasconnA->dwSize = CBRASCONNNEWA;
  8719. }
  8720. RetVal=(s_pfnRasEnumConnectionsA(lprasconnA, &cbConnections, lpcConnections));
  8721. // If the call succeeded, copy data back to the caller's buffer
  8722. if(RetVal==0)
  8723. {
  8724. DWORD iCon;
  8725. for(iCon = 0 ; iCon < *lpcConnections ; iCon++)
  8726. {
  8727. LPRASCONNW lprcw = &lprasconn[iCon];
  8728. LPRASCONNA lprca = &lprasconnA[iCon];
  8729. lprcw->hrasconn = lprca->hrasconn;
  8730. MultiByteToWideChar(g_acp, 0,
  8731. lprca->szEntryName, RAS_MaxEntryName,
  8732. lprcw->szEntryName, RAS_MaxEntryName);
  8733. MultiByteToWideChar(g_acp, 0,
  8734. lprca->szDeviceType, RAS_MaxDeviceType,
  8735. lprcw->szDeviceType, RAS_MaxDeviceType);
  8736. MultiByteToWideChar(g_acp, 0,
  8737. lprca->szDeviceName, RAS_MaxDeviceName,
  8738. lprcw->szDeviceName, RAS_MaxDeviceName);
  8739. if(!fNew)
  8740. {
  8741. lprcw->dwSize = CBRASCONNOLDW;
  8742. }
  8743. else
  8744. {
  8745. lprcw->dwSize = CBRASCONNNEWW;
  8746. lprcw->dwSubEntry = lprca->dwSubEntry;
  8747. MultiByteToWideChar(g_acp, 0,
  8748. lprca->szPhonebook, MAX_PATH,
  8749. lprcw->szPhonebook, MAX_PATH);
  8750. }
  8751. }
  8752. }
  8753. // In all cases, *lpcb should be updated
  8754. // with the correct size.
  8755. *lpcb = (*lpcConnections * lprasconn->dwSize);
  8756. }
  8757. return RetVal;
  8758. }
  8759. End=
  8760. [EFunc]
  8761. TemplateName=RasEnumDevicesW
  8762. Begin=
  8763. DWORD __stdcall
  8764. GodotRasEnumDevicesW(LPRASDEVINFOW lpRasDevInfo, LPDWORD lpcb, LPDWORD lpcDevices)
  8765. {
  8766. // if the call fails due to it not being on the OS (say like on
  8767. // win95), then it might return a "non-zero" error
  8768. // code, rather than using SetLastError. Godot will do both.
  8769. DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
  8770. if (s_pfnRasEnumDevicesA == NULL)
  8771. s_pfnRasEnumDevicesA = (pfnRED)GetRasProc("RasEnumDevicesA");
  8772. if (s_pfnRasEnumDevicesA)
  8773. {
  8774. UINT i;
  8775. DWORD cbAnsi = *lpcb;
  8776. if (lpRasDevInfo == NULL || cbAnsi == 0)
  8777. RetVal=(s_pfnRasEnumDevicesA(NULL, &cbAnsi, lpcDevices));
  8778. else
  8779. {
  8780. LPRASDEVINFOA lprdia;
  8781. _STACKALLOC(*lpcDevices * sizeof(RASDEVINFOA), lprdia);
  8782. if(lprdia==NULL)
  8783. return(ERROR_STACK_OVERFLOW);
  8784. lprdia->dwSize = sizeof(RASDEVINFOA);
  8785. RetVal=(s_pfnRasEnumDevicesA(lprdia, &cbAnsi, lpcDevices));
  8786. if(RetVal == 0)
  8787. {
  8788. for (i=0; i < *(lpcDevices); i++)
  8789. {
  8790. MultiByteToWideChar(g_acp,
  8791. 0,
  8792. lprdia[i].szDeviceType,
  8793. RAS_MaxDeviceType,
  8794. lpRasDevInfo[i].szDeviceType,
  8795. RAS_MaxDeviceType);
  8796. MultiByteToWideChar(g_acp,
  8797. 0,
  8798. lprdia[i].szDeviceName,
  8799. RAS_MaxDeviceName,
  8800. lpRasDevInfo[i].szDeviceName,
  8801. RAS_MaxDeviceName);
  8802. }
  8803. }
  8804. }
  8805. *lpcb = ((cbAnsi)/sizeof(RASDEVINFOA))*sizeof(RASDEVINFOW);
  8806. }
  8807. // Finished
  8808. return RetVal;
  8809. }
  8810. End=
  8811. [EFunc]
  8812. TemplateName=RasEnumEntriesW
  8813. Begin=
  8814. DWORD __stdcall
  8815. GodotRasEnumEntriesW( LPCWSTR reserved,
  8816. LPCWSTR lpszPhonebook,
  8817. LPRASENTRYNAMEW lprasentryname,
  8818. LPDWORD lpcb,
  8819. LPDWORD lpcEntries
  8820. )
  8821. {
  8822. // if the call fails due to it not being on the OS (say like on
  8823. // win95), then it might return a "non-zero" error
  8824. // code, rather than using SetLastError. Godot will do both.
  8825. DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
  8826. if (s_pfnRasEnumEntriesA == NULL)
  8827. s_pfnRasEnumEntriesA = (pfnREE)GetRasProc("RasEnumEntriesA");
  8828. if (s_pfnRasEnumEntriesA)
  8829. {
  8830. DWORD cbAnsi = *lpcb;
  8831. LPRASENTRYNAMEA lprena;
  8832. UINT i;
  8833. _STACKALLOC(cbAnsi * sizeof(RASENTRYNAMEA), lprena);
  8834. if(lprena==NULL)
  8835. return(ERROR_STACK_OVERFLOW);
  8836. lprena->dwSize = sizeof(RASENTRYNAMEA);
  8837. // Calling RasEnumEntries to enumerate the phone-book entries
  8838. RetVal = (s_pfnRasEnumEntriesA(NULL, NULL, lprena, &cbAnsi, lpcEntries));
  8839. if(RetVal == 0)
  8840. {
  8841. for (i=0; i < *(lpcEntries); i++)
  8842. {
  8843. MultiByteToWideChar(g_acp,
  8844. 0,
  8845. lprena[i].szEntryName,
  8846. RAS_MaxEntryName,
  8847. lprasentryname[i].szEntryName,
  8848. RAS_MaxEntryName);
  8849. lprena++;
  8850. lprasentryname++;
  8851. }
  8852. }
  8853. else
  8854. {
  8855. *lpcb = cbAnsi*sizeof(WCHAR);
  8856. }
  8857. }
  8858. // Finished
  8859. return RetVal;
  8860. UNREFERENCED_PARAMETER(lpszPhonebook);
  8861. }
  8862. End=
  8863. [EFunc]
  8864. TemplateName=RasGetConnectStatusW
  8865. Begin=
  8866. DWORD __stdcall
  8867. GodotRasGetConnectStatusW(HRASCONN hrasconn, LPRASCONNSTATUSW lprasconnstatus)
  8868. {
  8869. // if the call fails due to it not being on the OS (say like on
  8870. // win95), then it might return a "non-zero" error
  8871. // code, rather than using SetLastError. Godot will do both.
  8872. DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
  8873. if (s_pfnRasGetConnectStatusA == NULL)
  8874. s_pfnRasGetConnectStatusA = (pfnRGCS)GetRasProc("RasGetConnectStatusA");
  8875. if (s_pfnRasGetConnectStatusA)
  8876. {
  8877. RASCONNSTATUSA rcsa;
  8878. ZeroMemory(&rcsa, sizeof(RASCONNSTATUSA));
  8879. rcsa.dwSize = sizeof(RASCONNSTATUSA);
  8880. RetVal=(s_pfnRasGetConnectStatusA(hrasconn, &rcsa));
  8881. if(RetVal==0)
  8882. {
  8883. MultiByteToWideChar(g_acp, 0,
  8884. rcsa.szDeviceType, RAS_MaxDeviceType,
  8885. lprasconnstatus->szDeviceType, RAS_MaxDeviceType);
  8886. MultiByteToWideChar(g_acp, 0,
  8887. rcsa.szDeviceName, RAS_MaxDeviceName,
  8888. lprasconnstatus->szDeviceName, RAS_MaxDeviceName);
  8889. }
  8890. }
  8891. // Finished
  8892. return RetVal;
  8893. }
  8894. End=
  8895. [EFunc]
  8896. TemplateName=RasGetEntryDialParamsW
  8897. Begin=
  8898. DWORD __stdcall
  8899. GodotRasGetEntryDialParamsW(LPCWSTR lpszPhonebook, LPRASDIALPARAMSW lprasdialparams, LPBOOL lpfPassword)
  8900. {
  8901. // if the call fails due to it not being on the OS (say like on
  8902. // win95), then it might return a "non-zero" error
  8903. // code, rather than using SetLastError. Godot will do both.
  8904. DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
  8905. if (s_pfnRasGetEntryDialParamsA == NULL)
  8906. s_pfnRasGetEntryDialParamsA = (pfnRGEDP)GetRasProc("RasGetEntryDialParamsA");
  8907. if (s_pfnRasGetEntryDialParamsA)
  8908. {
  8909. LPRASDIALPARAMSA lprdpa;
  8910. BOOL fOldStruct = (lprasdialparams->dwSize == CBRASDIALPARAMSOLDW);
  8911. if(fOldStruct)
  8912. {
  8913. _STACKALLOC(CBRASDIALPARAMSOLDA, lprdpa);
  8914. if(lprdpa==NULL)
  8915. return(ERROR_STACK_OVERFLOW);
  8916. ZeroMemory(lprdpa, CBRASDIALPARAMSOLDA);
  8917. lprdpa->dwSize = CBRASDIALPARAMSOLDA;
  8918. }
  8919. else
  8920. {
  8921. _STACKALLOC(CBRASDIALPARAMSNEWA, lprdpa);
  8922. if(lprdpa==NULL)
  8923. return(ERROR_STACK_OVERFLOW);
  8924. ZeroMemory(lprdpa, CBRASDIALPARAMSNEWA);
  8925. lprdpa->dwSize = CBRASDIALPARAMSNEWA;
  8926. }
  8927. RetVal=(s_pfnRasGetEntryDialParamsA(NULL, lprdpa, lpfPassword));
  8928. if(RetVal==0)
  8929. {
  8930. MultiByteToWideChar(g_acp, 0,
  8931. lprdpa->szEntryName, RAS_MaxEntryName,
  8932. lprasdialparams->szEntryName, RAS_MaxEntryName);
  8933. MultiByteToWideChar(g_acp, 0,
  8934. lprdpa->szPhoneNumber, RAS_MaxPhoneNumber,
  8935. lprasdialparams->szPhoneNumber, RAS_MaxPhoneNumber);
  8936. MultiByteToWideChar(g_acp, 0,
  8937. lprdpa->szCallbackNumber, RAS_MaxCallbackNumber,
  8938. lprasdialparams->szCallbackNumber, RAS_MaxCallbackNumber);
  8939. MultiByteToWideChar(g_acp, 0,
  8940. lprdpa->szUserName, UNLEN,
  8941. lprasdialparams->szUserName, UNLEN);
  8942. MultiByteToWideChar(g_acp, 0,
  8943. lprdpa->szPassword, PWLEN,
  8944. lprasdialparams->szPassword, PWLEN);
  8945. MultiByteToWideChar(g_acp, 0,
  8946. lprdpa->szDomain, DNLEN,
  8947. lprasdialparams->szDomain, DNLEN);
  8948. if(!fOldStruct)
  8949. {
  8950. lprasdialparams->dwSubEntry = lprdpa->dwSubEntry ;
  8951. lprasdialparams->dwCallbackId = lprdpa->dwCallbackId;
  8952. }
  8953. }
  8954. }
  8955. // Finished
  8956. return RetVal;
  8957. UNREFERENCED_PARAMETER(lpszPhonebook);
  8958. }
  8959. End=
  8960. [EFunc]
  8961. TemplateName=RasGetEntryPropertiesW
  8962. Begin=
  8963. DWORD __stdcall
  8964. GodotRasGetEntryPropertiesW( LPCWSTR lpszPhonebook,
  8965. LPCWSTR lpszEntry,
  8966. LPRASENTRYW lpRasEntry,
  8967. DWORD * lpdwEntryInfoSize,
  8968. LPBYTE lpbDeviceInfo,
  8969. LPDWORD lpdwDeviceInfoSize
  8970. )
  8971. {
  8972. // We do not support dwAlternateOffset presently. Neither does QuintinB in
  8973. // the RAS Connection Manager. If this was needed then someone would have
  8974. // to do the work. For now its a known limitation of Godot.
  8975. // if the call fails due to it not being on the OS (say like on
  8976. // win95), then it might return a "non-zero" error
  8977. // code, rather than using SetLastError. Godot will do both.
  8978. DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
  8979. if (s_pfnRasGetEntryPropertiesA == NULL)
  8980. s_pfnRasGetEntryPropertiesA = (pfnRGEP)GetRasProc("RasGetEntryPropertiesA");
  8981. if (s_pfnRasGetEntryPropertiesA)
  8982. {
  8983. if(RAS_MaxEntryName < gwcslen(lpszEntry))
  8984. RetVal = ERROR_INVALID_PARAMETER;
  8985. else
  8986. {
  8987. char lpszEntryAnsi[RAS_MaxEntryName + 1];
  8988. LPRASENTRYA lprea;
  8989. DWORD dweisa;
  8990. BOOL f401Struct;
  8991. WideCharToMultiByte(g_acp, 0, lpszEntry, -1, lpszEntryAnsi, RAS_MaxEntryName, NULL, NULL);
  8992. if (lpRasEntry->dwSize > CBRASENTRYOLDW)
  8993. {
  8994. f401Struct = TRUE;
  8995. _STACKALLOC(CBRASENTRYOLDA, lprea);
  8996. if(lprea)
  8997. {
  8998. ZeroMemory(lprea, CBRASENTRYOLDA);
  8999. lprea->dwSize = CBRASENTRYOLDA;
  9000. dweisa = (DWORD)CBRASENTRYOLDA;
  9001. }
  9002. }
  9003. else
  9004. {
  9005. f401Struct = FALSE;
  9006. _STACKALLOC(CBRASENTRYNEWA, lprea);
  9007. if(lprea)
  9008. {
  9009. ZeroMemory(lprea, CBRASENTRYNEWA);
  9010. lprea->dwSize = CBRASENTRYNEWA;
  9011. dweisa = (DWORD)CBRASENTRYNEWA;
  9012. }
  9013. }
  9014. if(lprea==NULL)
  9015. {
  9016. return(ERROR_STACK_OVERFLOW);
  9017. }
  9018. RetVal=(s_pfnRasGetEntryPropertiesA(NULL, lpszEntryAnsi, lprea, &dweisa,
  9019. lpbDeviceInfo, lpdwDeviceInfoSize));
  9020. if((RetVal==ERROR_SUCCESS) && lpRasEntry)
  9021. {
  9022. lpRasEntry->dwfOptions = lprea->dwfOptions;
  9023. // Location/phone number.
  9024. lpRasEntry->dwCountryID = lprea->dwCountryID;
  9025. lpRasEntry->dwCountryCode = lprea->dwCountryCode;
  9026. MultiByteToWideChar(g_acp, 0, lprea->szAreaCode, RAS_MaxAreaCode, lpRasEntry->szAreaCode, RAS_MaxAreaCode);
  9027. MultiByteToWideChar(g_acp, 0, lprea->szLocalPhoneNumber, RAS_MaxPhoneNumber, lpRasEntry->szLocalPhoneNumber, RAS_MaxPhoneNumber);
  9028. lpRasEntry->dwAlternateOffset = lprea->dwAlternateOffset;
  9029. // PPP/Ip
  9030. memcpy(&(lpRasEntry->ipaddr), &(lprea->ipaddr), sizeof(RASIPADDR));
  9031. memcpy(&(lpRasEntry->ipaddrDns), &(lprea->ipaddrDns), sizeof(RASIPADDR));
  9032. memcpy(&(lpRasEntry->ipaddrDnsAlt), &(lprea->ipaddrDnsAlt), sizeof(RASIPADDR));
  9033. memcpy(&(lpRasEntry->ipaddrWins), &(lprea->ipaddrWins), sizeof(RASIPADDR));
  9034. memcpy(&(lpRasEntry->ipaddrWinsAlt), &(lprea->ipaddrWinsAlt), sizeof(RASIPADDR));
  9035. // Framing
  9036. lpRasEntry->dwFrameSize = lprea->dwFrameSize;
  9037. lpRasEntry->dwfNetProtocols = lprea->dwfNetProtocols;
  9038. lpRasEntry->dwFramingProtocol = lprea->dwFramingProtocol;
  9039. // Scripting
  9040. MultiByteToWideChar(g_acp, 0, lprea->szScript, MAX_PATH, lpRasEntry->szScript, MAX_PATH);
  9041. // AutoDial
  9042. MultiByteToWideChar(g_acp, 0, lprea->szAutodialDll, MAX_PATH, lpRasEntry->szAutodialDll, MAX_PATH);
  9043. MultiByteToWideChar(g_acp, 0, lprea->szAutodialFunc, MAX_PATH, lpRasEntry->szAutodialFunc, MAX_PATH);
  9044. // Device
  9045. MultiByteToWideChar(g_acp, 0, lprea->szDeviceType, RAS_MaxDeviceType, lpRasEntry->szDeviceType, RAS_MaxDeviceType);
  9046. MultiByteToWideChar(g_acp, 0, lprea->szDeviceName, RAS_MaxDeviceName, lpRasEntry->szDeviceName, RAS_MaxDeviceName);
  9047. // X.25
  9048. MultiByteToWideChar(g_acp, 0, lprea->szX25PadType, RAS_MaxPadType, lpRasEntry->szX25PadType, RAS_MaxPadType);
  9049. MultiByteToWideChar(g_acp, 0, lprea->szX25Address, RAS_MaxX25Address, lpRasEntry->szX25Address, RAS_MaxX25Address);
  9050. MultiByteToWideChar(g_acp, 0, lprea->szX25Facilities, RAS_MaxFacilities, lpRasEntry->szX25Facilities, RAS_MaxFacilities);
  9051. MultiByteToWideChar(g_acp, 0, lprea->szX25UserData, RAS_MaxUserData, lpRasEntry->szX25UserData, RAS_MaxUserData);
  9052. lpRasEntry->dwChannels = lprea->dwChannels;
  9053. // Reserved - no need to copy but no reason not to
  9054. lpRasEntry->dwReserved1 = lprea->dwReserved1;
  9055. lpRasEntry->dwReserved2 = lprea->dwReserved2;
  9056. if(f401Struct)
  9057. {
  9058. lpRasEntry->dwSubEntries = lprea->dwSubEntries;
  9059. lpRasEntry->dwDialMode = lprea->dwDialMode;
  9060. lpRasEntry->dwDialExtraPercent = lprea->dwDialExtraPercent;
  9061. lpRasEntry->dwDialExtraSampleSeconds = lprea->dwDialExtraSampleSeconds;
  9062. lpRasEntry->dwHangUpExtraPercent = lprea->dwHangUpExtraPercent;
  9063. lpRasEntry->dwHangUpExtraSampleSeconds = lprea->dwHangUpExtraSampleSeconds;
  9064. lpRasEntry->dwIdleDisconnectSeconds = lprea->dwIdleDisconnectSeconds;
  9065. }
  9066. }
  9067. else if ((ERROR_BUFFER_TOO_SMALL == RetVal) || !lpRasEntry)
  9068. {
  9069. // We don't know the actual size since we are passing a RASENTRYA, but
  9070. // the user only knows about RASENTRYW. Thus double the returned size
  9071. // and we will call it a day.
  9072. *lpdwEntryInfoSize = dweisa*sizeof(WCHAR);
  9073. }
  9074. }
  9075. }
  9076. // Finished
  9077. return RetVal;
  9078. UNREFERENCED_PARAMETER(lpszPhonebook);
  9079. }
  9080. End=
  9081. [EFunc]
  9082. TemplateName=RasGetErrorStringW
  9083. Begin=
  9084. DWORD __stdcall
  9085. GodotRasGetErrorStringW(UINT uErrorValue, LPWSTR lpszErrorString, DWORD cBufSize)
  9086. {
  9087. // if the call fails due to it not being on the OS (say like on
  9088. // win95), then it might return a "non-zero" error
  9089. // code, rather than using SetLastError. Godot will do both.
  9090. DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
  9091. if (s_pfnRasGetErrorStringA == NULL)
  9092. s_pfnRasGetErrorStringA = (pfnRGES)GetRasProc("RasGetErrorStringA");
  9093. if (s_pfnRasGetErrorStringA)
  9094. {
  9095. char lpszErrorStringAnsi[256 + 1];
  9096. RetVal=(s_pfnRasGetErrorStringA(uErrorValue, lpszErrorStringAnsi, cBufSize));
  9097. if (RetVal==ERROR_SUCCESS)
  9098. MultiByteToWideChar(g_acp, 0, lpszErrorStringAnsi, -1, lpszErrorString, cBufSize);
  9099. }
  9100. // Finished
  9101. return RetVal;
  9102. }
  9103. End=
  9104. [EFunc]
  9105. TemplateName=RasHangUpW
  9106. Begin=
  9107. DWORD __stdcall
  9108. GodotRasHangUpW(HRASCONN hrasconn)
  9109. {
  9110. // if the call fails due to it not being on the OS (say like on
  9111. // win95), then it might return a "non-zero" error
  9112. // code, rather than using SetLastError. Godot will do both.
  9113. DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
  9114. if (s_pfnRasHangUpA == NULL)
  9115. s_pfnRasHangUpA = (pfnRHU)GetRasProc("RasHangUpA");
  9116. if (s_pfnRasHangUpA)
  9117. {
  9118. // Why the heck is this function A/W decorated, anyway?
  9119. // Its not like there are any strings here!
  9120. RetVal=(s_pfnRasHangUpA(hrasconn));
  9121. }
  9122. return(RetVal);
  9123. }
  9124. End=
  9125. [EFunc]
  9126. TemplateName=RasRenameEntryW
  9127. Begin=
  9128. DWORD __stdcall
  9129. GodotRasRenameEntryW(LPCWSTR lpszPhonebook, LPCWSTR lpszOldEntry, LPCWSTR lpszNewEntry)
  9130. {
  9131. // if the call fails due to it not being on the OS (say like on
  9132. // win95), then it might return a "non-zero" error
  9133. // code, rather than using SetLastError. Godot will do both.
  9134. DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
  9135. if (s_pfnRasRenameEntryA == NULL)
  9136. s_pfnRasRenameEntryA = (pfnRRE)GetRasProc("RasRenameEntryA");
  9137. if (s_pfnRasRenameEntryA)
  9138. {
  9139. if((RAS_MaxEntryName < gwcslen(lpszOldEntry)) ||
  9140. (RAS_MaxEntryName < gwcslen(lpszNewEntry)))
  9141. RetVal = ERROR_INVALID_PARAMETER;
  9142. else
  9143. {
  9144. char lpszOldEntryAnsi[RAS_MaxEntryName + 1];
  9145. char lpszNewEntryAnsi[RAS_MaxEntryName + 1];
  9146. WideCharToMultiByte(g_acp, 0, lpszOldEntry, -1, lpszOldEntryAnsi, RAS_MaxEntryName, NULL, NULL);
  9147. WideCharToMultiByte(g_acp, 0, lpszNewEntry, -1, lpszNewEntryAnsi, RAS_MaxEntryName, NULL, NULL);
  9148. RetVal=(s_pfnRasRenameEntryA(NULL, lpszOldEntryAnsi, lpszNewEntryAnsi));
  9149. }
  9150. }
  9151. // Finished
  9152. return RetVal;
  9153. UNREFERENCED_PARAMETER(lpszPhonebook);
  9154. }
  9155. End=
  9156. [EFunc]
  9157. TemplateName=RasSetEntryDialParamsW
  9158. Begin=
  9159. DWORD __stdcall
  9160. GodotRasSetEntryDialParamsW(LPCWSTR lpszPhonebook, LPRASDIALPARAMSW lprasdialparams, BOOL fRemovePassword)
  9161. {
  9162. // if the call fails due to it not being on the OS (say like on
  9163. // win95), then it might return a "non-zero" error
  9164. // code, rather than using SetLastError. Godot will do both.
  9165. DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
  9166. if (s_pfnRasSetEntryDialParamsA == NULL)
  9167. s_pfnRasSetEntryDialParamsA = (pfnRSEDP)GetRasProc("RasSetEntryDialParamsA");
  9168. if (s_pfnRasSetEntryDialParamsA)
  9169. {
  9170. LPRASDIALPARAMSA lprdpa;
  9171. if (lprasdialparams->dwSize == CBRASDIALPARAMSOLDW)
  9172. {
  9173. _STACKALLOC(CBRASDIALPARAMSOLDA, lprdpa);
  9174. if(lprdpa)
  9175. lprdpa->dwSize = CBRASDIALPARAMSOLDA;
  9176. }
  9177. else
  9178. {
  9179. _STACKALLOC(CBRASDIALPARAMSNEWA, lprdpa);
  9180. if(lprdpa)
  9181. {
  9182. lprdpa->dwSize = CBRASDIALPARAMSNEWA;
  9183. lprdpa->dwSubEntry = lprasdialparams->dwSubEntry;
  9184. lprdpa->dwCallbackId = lprasdialparams->dwCallbackId;
  9185. }
  9186. }
  9187. if(lprdpa)
  9188. {
  9189. WideCharToMultiByte(g_acp, 0, lprasdialparams->szEntryName, RAS_MaxEntryName, lprdpa->szEntryName, RAS_MaxEntryName, NULL, NULL);
  9190. WideCharToMultiByte(g_acp, 0, lprasdialparams->szPhoneNumber, RAS_MaxPhoneNumber, lprdpa->szPhoneNumber, RAS_MaxPhoneNumber, NULL, NULL);
  9191. WideCharToMultiByte(g_acp, 0, lprasdialparams->szCallbackNumber, RAS_MaxCallbackNumber, lprdpa->szCallbackNumber, RAS_MaxCallbackNumber, NULL, NULL);
  9192. WideCharToMultiByte(g_acp, 0, lprasdialparams->szUserName, UNLEN, lprdpa->szUserName, UNLEN, NULL, NULL);
  9193. WideCharToMultiByte(g_acp, 0, lprasdialparams->szPassword, PWLEN, lprdpa->szPassword, PWLEN, NULL, NULL);
  9194. WideCharToMultiByte(g_acp, 0, lprasdialparams->szDomain, DNLEN, lprdpa->szDomain, DNLEN, NULL, NULL);
  9195. RetVal = (s_pfnRasSetEntryDialParamsA(NULL, lprdpa, fRemovePassword));
  9196. }
  9197. else
  9198. RetVal = ERROR_STACK_OVERFLOW;
  9199. }
  9200. return(RetVal);
  9201. UNREFERENCED_PARAMETER(lpszPhonebook);
  9202. }
  9203. End=
  9204. [EFunc]
  9205. TemplateName=RasSetEntryPropertiesW
  9206. Begin=
  9207. DWORD __stdcall
  9208. GodotRasSetEntryPropertiesW( LPCWSTR lpszPhonebook,
  9209. LPCWSTR lpszEntry,
  9210. LPRASENTRYW lpRasEntry,
  9211. DWORD dwEntryInfoSize,
  9212. LPBYTE lpbDeviceInfo,
  9213. DWORD dwDeviceInfoSize
  9214. )
  9215. {
  9216. // We do not support dwAlternateOffset presently. Neither does QuintinB
  9217. // in the RAS Connection Manager. If this was needed then someone would
  9218. // have to do the work. For now its a limitation of Godot.
  9219. // if the call fails due to it not being on the OS (say like on
  9220. // win95), then it might return a "non-zero" error code
  9221. DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
  9222. if (s_pfnRasSetEntryPropertiesA == NULL)
  9223. s_pfnRasSetEntryPropertiesA = (pfnRSEP)GetRasProc("RasSetEntryPropertiesA");
  9224. if (s_pfnRasSetEntryPropertiesA)
  9225. {
  9226. if(RAS_MaxEntryName < gwcslen(lpszEntry))
  9227. RetVal = ERROR_INVALID_PARAMETER;
  9228. else
  9229. {
  9230. LPRASENTRYA lprea;
  9231. char lpszEntryAnsi[RAS_MaxEntryName];
  9232. _STACKALLOC(CBRASENTRYNEWA, lprea);
  9233. if(lprea==NULL)
  9234. {
  9235. return(ERROR_STACK_OVERFLOW);
  9236. }
  9237. WideCharToMultiByte(g_acp, 0, lpszEntry, -1, lpszEntryAnsi, RAS_MaxEntryName, NULL, NULL);
  9238. ZeroMemory(lprea, CBRASENTRYNEWA);
  9239. lprea->dwfOptions = lpRasEntry->dwfOptions;
  9240. lprea->dwCountryID = lpRasEntry->dwCountryID;
  9241. lprea->dwCountryCode = lpRasEntry->dwCountryCode;
  9242. WideCharToMultiByte(g_acp, 0, lpRasEntry->szAreaCode, RAS_MaxAreaCode, lprea->szAreaCode, RAS_MaxAreaCode, NULL, NULL);
  9243. WideCharToMultiByte(g_acp, 0, lpRasEntry->szLocalPhoneNumber, RAS_MaxPhoneNumber, lprea->szLocalPhoneNumber, RAS_MaxPhoneNumber, NULL, NULL);
  9244. lprea->dwAlternateOffset = lpRasEntry->dwAlternateOffset;
  9245. memcpy(&(lprea->ipaddr), &(lpRasEntry->ipaddr), sizeof(RASIPADDR));
  9246. memcpy(&(lprea->ipaddrDns), &(lpRasEntry->ipaddrDns), sizeof(RASIPADDR));
  9247. memcpy(&(lprea->ipaddrDnsAlt), &(lpRasEntry->ipaddrDnsAlt), sizeof(RASIPADDR));
  9248. memcpy(&(lprea->ipaddrWins), &(lpRasEntry->ipaddrWins), sizeof(RASIPADDR));
  9249. memcpy(&(lprea->ipaddrWinsAlt), &(lpRasEntry->ipaddrWinsAlt), sizeof(RASIPADDR));
  9250. lprea->dwFrameSize = lpRasEntry->dwFrameSize;
  9251. lprea->dwfNetProtocols = lpRasEntry->dwfNetProtocols;
  9252. lprea->dwFramingProtocol = lpRasEntry->dwFramingProtocol;
  9253. WideCharToMultiByte(g_acp, 0, lpRasEntry->szScript, MAX_PATH, lprea->szScript, MAX_PATH, NULL, NULL);
  9254. WideCharToMultiByte(g_acp, 0, lpRasEntry->szAutodialDll, MAX_PATH, lprea->szAutodialDll, MAX_PATH, NULL, NULL);
  9255. WideCharToMultiByte(g_acp, 0, lpRasEntry->szAutodialFunc, MAX_PATH, lprea->szAutodialFunc, MAX_PATH, NULL, NULL);
  9256. WideCharToMultiByte(g_acp, 0, lpRasEntry->szDeviceType, RAS_MaxDeviceType, lprea->szDeviceType, RAS_MaxDeviceType, NULL, NULL);
  9257. WideCharToMultiByte(g_acp, 0, lpRasEntry->szDeviceName, RAS_MaxDeviceName, lprea->szDeviceName, RAS_MaxDeviceName, NULL, NULL);
  9258. WideCharToMultiByte(g_acp, 0, lpRasEntry->szX25PadType, RAS_MaxPadType, lprea->szX25PadType, RAS_MaxPadType, NULL, NULL);
  9259. WideCharToMultiByte(g_acp, 0, lpRasEntry->szX25Address, RAS_MaxX25Address, lprea->szX25Address, RAS_MaxX25Address, NULL, NULL);
  9260. WideCharToMultiByte(g_acp, 0, lpRasEntry->szX25Facilities, RAS_MaxFacilities, lprea->szX25Facilities, RAS_MaxFacilities, NULL, NULL);
  9261. WideCharToMultiByte(g_acp, 0, lpRasEntry->szX25UserData, RAS_MaxUserData, lprea->szX25UserData, RAS_MaxUserData, NULL, NULL);
  9262. lprea->dwChannels = lpRasEntry->dwChannels;
  9263. lprea->dwReserved1 = lpRasEntry->dwReserved1;
  9264. lprea->dwReserved2 = lpRasEntry->dwReserved2;
  9265. if (lpRasEntry->dwSize > CBRASENTRYOLDW)
  9266. lprea->dwSize = CBRASENTRYOLDA;
  9267. else
  9268. {
  9269. lprea->dwSize = CBRASENTRYNEWA;
  9270. lprea->dwSubEntries = lpRasEntry->dwSubEntries;
  9271. lprea->dwDialMode = lpRasEntry->dwDialMode;
  9272. lprea->dwDialExtraPercent = lpRasEntry->dwDialExtraPercent;
  9273. lprea->dwDialExtraSampleSeconds = lpRasEntry->dwDialExtraSampleSeconds;
  9274. lprea->dwHangUpExtraPercent = lpRasEntry->dwHangUpExtraPercent;
  9275. lprea->dwHangUpExtraSampleSeconds = lpRasEntry->dwHangUpExtraSampleSeconds;
  9276. lprea->dwIdleDisconnectSeconds = lpRasEntry->dwIdleDisconnectSeconds;
  9277. }
  9278. RetVal=(s_pfnRasSetEntryPropertiesA(NULL, lpszEntryAnsi, lprea, dwEntryInfoSize,
  9279. lpbDeviceInfo, dwDeviceInfoSize));
  9280. }
  9281. }
  9282. // Finished
  9283. return RetVal;
  9284. UNREFERENCED_PARAMETER(lpszPhonebook);
  9285. }
  9286. End=
  9287. [EFunc]
  9288. TemplateName=RasSetSubEntryPropertiesW
  9289. Begin=
  9290. DWORD __stdcall
  9291. GodotRasSetSubEntryPropertiesW(LPCWSTR lpszPhonebook, LPCWSTR lpszEntry, DWORD dwSubEntry,
  9292. struct tagRASSUBENTRYW * lpRasSubEntry, DWORD dwcbRasSubEntry,
  9293. LPBYTE lpbDeviceConfig, DWORD dwcbDeviceConfig)
  9294. {
  9295. // if the call fails due to it not being on the OS (say like on
  9296. // win95/win98), then it might return a "non-zero" error code.
  9297. DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
  9298. if (s_pfnRasSetSubEntryPropertiesA == NULL)
  9299. s_pfnRasSetSubEntryPropertiesA = (pfnRSSEP)GetRasProc("RasSetSubEntryPropertiesA");
  9300. if (s_pfnRasSetSubEntryPropertiesA)
  9301. {
  9302. CHAR lpszEntryAnsi[RAS_MaxEntryName + 1];
  9303. int cch = WideCharToMultiByte(g_acp, 0, lpszEntry, -1, lpszEntryAnsi, RAS_MaxEntryName, NULL, NULL);
  9304. if(cch && (RAS_MaxEntryName >= cch))
  9305. {
  9306. LPRASSUBENTRYA lpRasSubEntryA;
  9307. DWORD dwcbRasSubEntryA;
  9308. size_t cchSub;
  9309. if(lpRasSubEntry->dwAlternateOffset)
  9310. cchSub = cchUnicodeMultiSz((LPWSTR)lpRasSubEntry + lpRasSubEntry->dwAlternateOffset);
  9311. else
  9312. cchSub = 0;
  9313. dwcbRasSubEntryA = sizeof(RASENTRYA) + (cchSub * g_mcs);
  9314. _STACKALLOC(dwcbRasSubEntryA, lpRasSubEntryA);
  9315. if(lpRasSubEntryA==NULL)
  9316. return(ERROR_STACK_OVERFLOW);
  9317. ZeroMemory(lpRasSubEntryA, dwcbRasSubEntryA);
  9318. lpRasSubEntryA->dwSize = sizeof(RASSUBENTRYA);
  9319. lpRasSubEntryA->dwfFlags = lpRasSubEntry->dwfFlags;
  9320. //
  9321. // Device
  9322. //
  9323. WideCharToMultiByte(g_acp,
  9324. 0,
  9325. lpRasSubEntry->szDeviceType,
  9326. RAS_MaxDeviceType,
  9327. lpRasSubEntryA->szDeviceType,
  9328. RAS_MaxDeviceType,
  9329. NULL,
  9330. NULL);
  9331. WideCharToMultiByte(g_acp,
  9332. 0,
  9333. lpRasSubEntry->szDeviceName,
  9334. RAS_MaxDeviceName,
  9335. lpRasSubEntryA->szDeviceName,
  9336. RAS_MaxDeviceName,
  9337. NULL,
  9338. NULL);
  9339. //
  9340. // Location/phone number.
  9341. //
  9342. WideCharToMultiByte(g_acp,
  9343. 0,
  9344. lpRasSubEntry->szLocalPhoneNumber,
  9345. RAS_MaxPhoneNumber,
  9346. lpRasSubEntryA->szLocalPhoneNumber,
  9347. RAS_MaxPhoneNumber,
  9348. NULL,
  9349. NULL);
  9350. WideCharToMultiByte(g_acp,
  9351. 0,
  9352. (LPWSTR)lpRasSubEntry + lpRasSubEntry->dwAlternateOffset,
  9353. cchSub,
  9354. (LPSTR)lpRasSubEntry + lpRasSubEntry->dwAlternateOffset,
  9355. cchSub * g_mcs,
  9356. NULL,
  9357. NULL);
  9358. RetVal=(s_pfnRasSetSubEntryPropertiesA(NULL, lpszEntryAnsi, dwSubEntry, lpRasSubEntryA,
  9359. dwcbRasSubEntryA, lpbDeviceConfig, dwcbDeviceConfig));
  9360. }
  9361. else
  9362. RetVal = ERROR_INVALID_PARAMETER;
  9363. }
  9364. // Finished
  9365. return RetVal;
  9366. UNREFERENCED_PARAMETER(lpszPhonebook);
  9367. }
  9368. End=
  9369. [EFunc]
  9370. TemplateName=RasValidateEntryNameW
  9371. Begin=
  9372. DWORD __stdcall GodotRasValidateEntryNameW(LPCWSTR lpszPhonebook, LPCWSTR lpszEntry)
  9373. {
  9374. // if the call fails due to it not being on the OS (say like on
  9375. // win95), then it might return a "non-zero" error code.
  9376. DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
  9377. if (s_pfnRasValidateEntryNameA == NULL)
  9378. s_pfnRasValidateEntryNameA = (pfnRVEN)GetRasProc("RasValidateEntryNameA");
  9379. if (s_pfnRasValidateEntryNameA)
  9380. {
  9381. if(RAS_MaxEntryName < gwcslen(lpszEntry))
  9382. RetVal = ERROR_INVALID_PARAMETER;
  9383. else
  9384. {
  9385. char lpszEntryAnsi[RAS_MaxEntryName];
  9386. WideCharToMultiByte(g_acp, 0, lpszEntry, -1, lpszEntryAnsi, RAS_MaxEntryName, NULL, NULL);
  9387. RetVal=(s_pfnRasValidateEntryNameA(NULL, lpszEntryAnsi));
  9388. }
  9389. }
  9390. // Finished
  9391. return RetVal;
  9392. UNREFERENCED_PARAMETER(lpszPhonebook);
  9393. }
  9394. End=
  9395. [EFunc]
  9396. TemplateName=RealGetWindowClassW
  9397. Begin=
  9398. UINT __stdcall
  9399. GodotRealGetWindowClassW(HWND hwnd, LPWSTR pszType, UINT cchType)
  9400. {
  9401. // Begin locals
  9402. UINT RetVal;
  9403. LPSTR pszTypeAnsi;
  9404. _STACKALLOC((cchType*g_mcs)+1, pszTypeAnsi);
  9405. // Call the 'A' version of the API
  9406. RetVal=RealGetWindowClassA(hwnd, pszTypeAnsi, cchType);
  9407. // Begin postcall
  9408. if(RetVal)
  9409. {
  9410. MultiByteToWideChar(g_acp, 0, pszTypeAnsi, -1, pszType, cchType);
  9411. }
  9412. else if(pszType)
  9413. {
  9414. *pszType = 0;
  9415. }
  9416. // Finished
  9417. return RetVal;
  9418. }
  9419. End=
  9420. [EFunc]
  9421. TemplateName=ReadConsoleOutputCharacterW
  9422. Begin=
  9423. BOOL __stdcall
  9424. GodotReadConsoleOutputCharacterW( HANDLE hConsoleOutput,
  9425. LPWSTR lpCharacter,
  9426. DWORD nLength,
  9427. COORD dwReadCoord,
  9428. LPDWORD lpcchRead
  9429. )
  9430. {
  9431. // Begin locals
  9432. BOOL RetVal;
  9433. LPSTR lpCharacterAnsi;
  9434. _STACKALLOC((nLength*g_mcs)+1, lpCharacterAnsi);
  9435. if(lpCharacterAnsi==NULL && lpCharacter != NULL)
  9436. {
  9437. SetLastError(ERROR_STACK_OVERFLOW);
  9438. return(FALSE);
  9439. }
  9440. // Call the 'A' version of the API
  9441. RetVal=ReadConsoleOutputCharacterA(hConsoleOutput, lpCharacterAnsi, nLength, dwReadCoord, lpcchRead);
  9442. // Begin postcall
  9443. if(RetVal && lpCharacter && lpCharacterAnsi)
  9444. MultiByteToWideChar(g_oemcp, 0, lpCharacterAnsi, -1, lpCharacter, *(lpcchRead));
  9445. // Finished
  9446. return RetVal;
  9447. }
  9448. End=
  9449. [EFunc]
  9450. TemplateName=RegEnumKeyW
  9451. Begin=
  9452. LONG __stdcall
  9453. GodotRegEnumKeyW(HKEY hKey, DWORD dwIndex, LPWSTR lpName, DWORD cbName)
  9454. {
  9455. // Begin locals
  9456. LONG RetVal;
  9457. LPSTR lpNameAnsi;
  9458. // Copied from the OS API's param validation
  9459. if (IsBadWritePtr(lpName, cbName))
  9460. return ERROR_INVALID_PARAMETER;
  9461. // Alloc a string of like size.
  9462. _STACKALLOC((cbName*g_mcs)+1, lpNameAnsi);
  9463. if(lpNameAnsi==NULL)
  9464. {
  9465. SetLastError(ERROR_STACK_OVERFLOW);
  9466. return(0);
  9467. }
  9468. // Call the 'A' version of the API
  9469. RetVal=RegEnumKeyA(hKey, dwIndex, lpNameAnsi, cbName);
  9470. // Begin postcall
  9471. if(RetVal == ERROR_SUCCESS)
  9472. MultiByteToWideChar(g_acp, 0, lpNameAnsi, -1, lpName, cbName);
  9473. // Finished
  9474. return RetVal;
  9475. }
  9476. End=
  9477. [EFunc]
  9478. TemplateName=RegEnumKeyExW
  9479. Begin=
  9480. LONG __stdcall
  9481. GodotRegEnumKeyExW( HKEY hKey,
  9482. DWORD dwIndex,
  9483. LPWSTR lpName,
  9484. LPDWORD lpcbName,
  9485. LPDWORD lpReserved,
  9486. LPWSTR lpClass,
  9487. LPDWORD lpcbClass,
  9488. PFILETIME lpftLWT
  9489. )
  9490. {
  9491. // Begin locals
  9492. LONG RetVal;
  9493. LPSTR lpNameAnsi, lpClassAnsi;
  9494. DWORD cbName, cbClass;
  9495. if (lpcbName)
  9496. {
  9497. cbName = sizeof(WCHAR) * *lpcbName;
  9498. _STACKALLOC(cbName, lpNameAnsi);
  9499. }
  9500. else
  9501. {
  9502. cbName = 0;
  9503. lpNameAnsi = NULL;
  9504. }
  9505. if (lpcbClass)
  9506. {
  9507. cbClass = sizeof(WCHAR) * (*lpcbClass);
  9508. _STACKALLOC(cbClass, lpClassAnsi);
  9509. }
  9510. else
  9511. {
  9512. cbClass = 0;
  9513. lpClassAnsi = NULL;
  9514. }
  9515. // Call the 'A' version of the API
  9516. RetVal=RegEnumKeyExA(hKey, dwIndex, lpNameAnsi, &cbName, lpReserved, lpClassAnsi, &cbClass, lpftLWT);
  9517. // Begin postcall
  9518. if(RetVal == ERROR_SUCCESS)
  9519. {
  9520. DWORD cch;
  9521. if(lpName && lpcbName)
  9522. {
  9523. cch = MultiByteToWideChar(g_acp, 0, lpNameAnsi, cbName, lpName, *lpcbName);
  9524. if(cbName && !cch)
  9525. RetVal = ERROR_BUFFER_OVERFLOW;
  9526. *lpcbName = cch;
  9527. }
  9528. else if (lpcbName)
  9529. {
  9530. *lpcbName = 0;
  9531. }
  9532. if(lpClass && lpcbClass)
  9533. {
  9534. cch = MultiByteToWideChar(g_acp, 0, lpClassAnsi, cbClass, lpClass, *lpcbClass);
  9535. if(cbName && !cch)
  9536. RetVal = ERROR_BUFFER_OVERFLOW;
  9537. *lpcbClass = cch;
  9538. }
  9539. else if (lpcbClass)
  9540. {
  9541. *lpcbClass = 0;
  9542. }
  9543. }
  9544. // Finished
  9545. return RetVal;
  9546. }
  9547. End=
  9548. [EFunc]
  9549. TemplateName=RegEnumValueW
  9550. Begin=
  9551. LONG __stdcall GodotRegEnumValueW( HKEY hKey,
  9552. DWORD dwIndex,
  9553. LPWSTR lpValueName,
  9554. LPDWORD lpcbValueName, // this is cch, not cb, in the W case!!!
  9555. LPDWORD lpReserved,
  9556. LPDWORD lpType, // may be NULL
  9557. LPBYTE lpData, // may be NULL
  9558. LPDWORD lpcbData) // may be NULL -- but only if lpData is NULL
  9559. {
  9560. // Begin locals
  9561. LONG RetVal;
  9562. LPSTR szValue;
  9563. DWORD dwType;
  9564. DWORD cbValueName;
  9565. DWORD cbData;
  9566. // Required pointers:
  9567. if (!lpValueName || !lpcbValueName || (!lpcbData && lpData))
  9568. {
  9569. return ERROR_INVALID_PARAMETER;
  9570. }
  9571. cbValueName = *lpcbValueName;
  9572. _STACKALLOC((cbValueName)*g_mcs, szValue);
  9573. if(szValue==NULL)
  9574. {
  9575. return(ERROR_STACK_OVERFLOW);
  9576. }
  9577. if(lpcbData)
  9578. cbData = *lpcbData;
  9579. else
  9580. cbData = 0;
  9581. // First call for informational purposes: type, etc. We
  9582. // do get the name, here (since we always get the name).
  9583. RetVal = RegEnumValueA(hKey, dwIndex, szValue, &cbValueName, lpReserved, &dwType, NULL, &cbData);
  9584. // Always copy the type info if the caller asked for it
  9585. if(lpType)
  9586. *lpType = dwType;
  9587. if(RetVal != ERROR_SUCCESS)
  9588. {
  9589. if(lpcbData)
  9590. *lpcbData = cbData;
  9591. if(lpcbValueName)
  9592. *lpcbValueName = cbValueName;
  9593. }
  9594. else
  9595. {
  9596. // We should always make it here unless they did something *really* awful
  9597. *lpcbValueName = MultiByteToWideChar(g_acp, 0, szValue, cbValueName, lpValueName, *lpcbValueName);
  9598. if(*lpcbValueName == 0)
  9599. {
  9600. // They did not give us enough of a buffer: this can happen on
  9601. // DBCS platforms with single-byte data (the *g_mcs buffer we
  9602. // allocated was big enough, but theirs is not).
  9603. RetVal = ERROR_INSUFFICIENT_BUFFER;
  9604. lpValueName[0] = L'\0';
  9605. // Note that the buffer we will ask for (below)
  9606. // can be bigger than necessary for the DBCS case.
  9607. *lpcbValueName = cbValueName * sizeof(WCHAR);
  9608. }
  9609. else if(lpData && lpcbData)
  9610. {
  9611. switch(dwType)
  9612. {
  9613. case REG_SZ:
  9614. case REG_EXPAND_SZ:
  9615. case REG_MULTI_SZ:
  9616. {
  9617. // we got the size already, so lets use it
  9618. LPSTR lpDataAnsi = GodotHeapAlloc(cbData);
  9619. if(lpDataAnsi==NULL)
  9620. {
  9621. return(ERROR_OUTOFMEMORY);
  9622. }
  9623. RetVal = RegEnumValueA(hKey, dwIndex, szValue, &cbValueName,
  9624. lpReserved, &dwType, (LPBYTE)lpDataAnsi, &cbData);
  9625. if(dwType==REG_MULTI_SZ)
  9626. {
  9627. DWORD cchData = GrszToGrwz(lpDataAnsi, (LPWSTR)lpData, *lpcbData/sizeof(WCHAR));
  9628. // If they did not give us enough buffer, tell them!
  9629. if ((*lpcbData > 0) && (cchData > *lpcbData/sizeof(WCHAR)))
  9630. RetVal = ERROR_MORE_DATA;
  9631. *lpcbData = cchData * sizeof(WCHAR);
  9632. }
  9633. else
  9634. {
  9635. LPWSTR lpDataT;
  9636. _STACKALLOC(cbData * sizeof(WCHAR), lpDataT);
  9637. MultiByteToWideChar(g_acp, 0, lpDataAnsi, cbData, lpDataT, cbData);
  9638. cbData = gwcslen(lpDataT) * sizeof(WCHAR);
  9639. if (cbData > *lpcbData)
  9640. {
  9641. // If they did not give us enough buffer, tell them!
  9642. if(*lpcbData > 0)
  9643. RetVal = ERROR_MORE_DATA;
  9644. }
  9645. else
  9646. {
  9647. RetVal = ERROR_SUCCESS;
  9648. memcpy(lpData, lpDataT, cbData);
  9649. }
  9650. *lpcbData = cbData;
  9651. }
  9652. GodotHeapFree(lpDataAnsi);
  9653. break;
  9654. }
  9655. default:
  9656. {
  9657. // some non-string type of data: the name has
  9658. // been done, let the API do all of the rest now.
  9659. RetVal = RegEnumValueA(hKey, dwIndex, szValue, &cbValueName,
  9660. lpReserved, lpType, lpData, lpcbData);
  9661. break;
  9662. }
  9663. }
  9664. }
  9665. }
  9666. // Finished
  9667. return RetVal;
  9668. }
  9669. End=
  9670. [EFunc]
  9671. TemplateName=RegisterDeviceNotificationW
  9672. Begin=
  9673. HDEVNOTIFY __stdcall
  9674. GodotRegisterDeviceNotificationW(HANDLE hRecipient, LPVOID NotificationFilter, DWORD Flags)
  9675. {
  9676. // Begin locals
  9677. HDEVNOTIFY RetVal = NULL;
  9678. __try
  9679. {
  9680. if (s_pfnRegisterDeviceNotificationA == NULL)
  9681. {
  9682. // Must allocate stuff for this API call
  9683. s_pfnRegisterDeviceNotificationA = (PFNrdna)GetUserProc("RegisterDeviceNotificationA");
  9684. }
  9685. if (s_pfnRegisterDeviceNotificationA)
  9686. {
  9687. size_t NameLength;
  9688. PDEV_BROADCAST_HDR dbh = NotificationFilter;
  9689. if (dbh->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
  9690. {
  9691. PDEV_BROADCAST_DEVICEINTERFACE_A dbdia;
  9692. PDEV_BROADCAST_DEVICEINTERFACE_W dbdiw = NotificationFilter;
  9693. _STACKALLOC(sizeof(DEV_BROADCAST_DEVICEINTERFACE_A), dbdia);
  9694. if(dbdia==NULL)
  9695. {
  9696. SetLastError(ERROR_STACK_OVERFLOW);
  9697. return(0);
  9698. }
  9699. ZeroMemory(dbdia, sizeof(DEV_BROADCAST_DEVICEINTERFACE_A));
  9700. dbdia->dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE_A);
  9701. dbdia->dbcc_devicetype = dbdiw->dbcc_devicetype;
  9702. dbdia->dbcc_reserved = dbdiw->dbcc_reserved;
  9703. dbdia->dbcc_classguid = dbdiw->dbcc_classguid;
  9704. NameLength = gwcslen(dbdiw->dbcc_name);
  9705. *(char **)(dbdia->dbcc_name) = _alloca(NameLength);
  9706. WideCharToMultiByte(g_acp, 0,
  9707. dbdiw->dbcc_name, NameLength,
  9708. dbdia->dbcc_name, NameLength,
  9709. NULL, NULL);
  9710. RetVal = (s_pfnRegisterDeviceNotificationA (hRecipient, dbdia, Flags));
  9711. }
  9712. else if(dbh->dbch_devicetype == DBT_DEVTYP_PORT)
  9713. {
  9714. PDEV_BROADCAST_PORT_A dbpa;
  9715. PDEV_BROADCAST_PORT_W dbpw = NotificationFilter;
  9716. _STACKALLOC(sizeof(DEV_BROADCAST_PORT_A), dbpa);
  9717. if(dbpa==NULL)
  9718. {
  9719. SetLastError(ERROR_STACK_OVERFLOW);
  9720. return(0);
  9721. }
  9722. ZeroMemory(dbpa, sizeof(DEV_BROADCAST_PORT_A));
  9723. dbpa->dbcp_size = sizeof(DEV_BROADCAST_PORT_A);
  9724. dbpa->dbcp_devicetype = dbpw->dbcp_devicetype;
  9725. dbpa->dbcp_reserved = dbpw->dbcp_reserved;
  9726. NameLength = gwcslen(dbpw->dbcp_name);
  9727. *(char **)(dbpa->dbcp_name) = _alloca(NameLength);
  9728. WideCharToMultiByte(g_acp, 0,
  9729. dbpw->dbcp_name, NameLength,
  9730. dbpa->dbcp_name, NameLength,
  9731. NULL, NULL);
  9732. RetVal = (s_pfnRegisterDeviceNotificationA (hRecipient, dbpa, Flags));
  9733. }
  9734. else
  9735. {
  9736. // No changes needed! There are no strings in the other structures.
  9737. RetVal = (s_pfnRegisterDeviceNotificationA (hRecipient, NotificationFilter, Flags));
  9738. }
  9739. }
  9740. else
  9741. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  9742. }
  9743. __except( EXCEPTION_EXECUTE_HANDLER )
  9744. {
  9745. gresetstkoflw();
  9746. SetLastError(ERROR_STACK_OVERFLOW);
  9747. RetVal = 0;
  9748. }
  9749. // Finished
  9750. return RetVal;
  9751. }
  9752. End=
  9753. [EFunc]
  9754. TemplateName=RegQueryInfoKeyW
  9755. Begin=
  9756. LONG __stdcall
  9757. GodotRegQueryInfoKeyW( HKEY hKey,
  9758. LPWSTR lpClass,
  9759. LPDWORD lpcbClass,
  9760. LPDWORD lpReserved,
  9761. LPDWORD lpcSubKeys,
  9762. LPDWORD lpcbMaxSubKeyLen,
  9763. LPDWORD lpcbMaxClassLen,
  9764. LPDWORD lpcValues,
  9765. LPDWORD lpcbMaxValueNameLen,
  9766. LPDWORD lpcbMaxValueLen,
  9767. LPDWORD lpcbSecurityDescriptor,
  9768. PFILETIME lpftLastWriteTime
  9769. )
  9770. {
  9771. // Call the 'A' version of the API: Since there are no defined classess, we will
  9772. // conveniently ignore the param, thus giving us nothing to convert!
  9773. // We will pass the class and cbClass as is so that the API can validate for us.
  9774. return(RegQueryInfoKeyA(hKey,
  9775. (LPSTR)lpClass,
  9776. lpcbClass,
  9777. lpReserved,
  9778. lpcSubKeys,
  9779. lpcbMaxSubKeyLen,
  9780. lpcbMaxClassLen,
  9781. lpcValues,
  9782. lpcbMaxValueNameLen,
  9783. lpcbMaxValueLen,
  9784. lpcbSecurityDescriptor,
  9785. lpftLastWriteTime
  9786. ));
  9787. }
  9788. End=
  9789. [EFunc]
  9790. TemplateName=RegQueryMultipleValuesW
  9791. Begin=
  9792. // Max size for reg keys and values on Win9x
  9793. #define MAXREGKEYVALUESIZE 256
  9794. LONG __stdcall
  9795. GodotRegQueryMultipleValuesW( HKEY hKey,
  9796. PVALENTW val_list,
  9797. DWORD num_vals,
  9798. LPWSTR lpValueBuf,
  9799. LPDWORD ldwTotsize
  9800. )
  9801. {
  9802. LPSTR lpValueBufA = NULL;
  9803. PVALENTA val_listA = NULL;
  9804. LPSTR rgszNames = NULL;
  9805. LPSTR szName;
  9806. DWORD cchValue;
  9807. DWORD cbName;
  9808. LPDWORD pdwTotsize;
  9809. DWORD dwTotsize;
  9810. DWORD dwOffset;
  9811. UINT i;
  9812. LONG RetVal;
  9813. // Begin precall: we alloc on the heap here because NT does and
  9814. // because people can ask for a whole lot of memory!
  9815. // Alloc the space for the registry value information
  9816. val_listA = GodotHeapAlloc(sizeof(VALENTA) * num_vals);
  9817. if(val_listA == NULL)
  9818. {
  9819. RetVal = ERROR_OUTOFMEMORY;
  9820. goto Cleanup;
  9821. }
  9822. // Alloc the space for the registry names
  9823. rgszNames = GodotHeapAlloc(MAXREGKEYVALUESIZE * num_vals);
  9824. if(rgszNames == NULL)
  9825. {
  9826. RetVal = ERROR_OUTOFMEMORY;
  9827. goto Cleanup;
  9828. }
  9829. // Copy over their VALENTW info into our VALENTA, grabbing memory
  9830. // for the value names as needed.
  9831. szName = rgszNames;
  9832. dwOffset = 0;
  9833. for (i=0; i<num_vals; i++)
  9834. {
  9835. if (FSTRING_VALID(val_list[i].ve_valuename))
  9836. {
  9837. cbName = WideCharToMultiByte(g_acp,
  9838. 0,
  9839. val_list[i].ve_valuename,
  9840. gwcslen(val_list[i].ve_valuename),
  9841. szName,
  9842. MAXREGKEYVALUESIZE,
  9843. NULL,
  9844. NULL);
  9845. val_listA[i].ve_valuename = szName;
  9846. szName += cbName;
  9847. dwOffset += cbName;
  9848. }
  9849. else
  9850. {
  9851. // Consider: isn't this impossible? C'mon now, it must be, right?
  9852. }
  9853. }
  9854. // CONSIDER: Do we want to realloc rgszNames now? At the moment it is
  9855. // (MAXREGKEYVALUESIZE * num_vals) and it only needs to be dwOffset.
  9856. // Not sure if the perf hit of the realloc to shrink is worth the
  9857. // gaining back of that extra heap space.
  9858. // Now allocate our buffer for everything. We know we have Unicode strings
  9859. // worth of space here, but perhaps there are no string values so we
  9860. // have to have an equally sized buffer
  9861. if(!ldwTotsize || (*ldwTotsize==0))
  9862. {
  9863. dwTotsize = 0;
  9864. lpValueBufA = NULL;
  9865. }
  9866. else
  9867. {
  9868. dwTotsize = *ldwTotsize;
  9869. lpValueBufA = GodotHeapAlloc(dwTotsize);
  9870. if(rgszNames == NULL)
  9871. {
  9872. RetVal = ERROR_OUTOFMEMORY;
  9873. goto Cleanup;
  9874. }
  9875. }
  9876. pdwTotsize = &dwTotsize;
  9877. // We made it this far, so call the API
  9878. RetVal=RegQueryMultipleValuesA(hKey, val_listA, num_vals, lpValueBufA, pdwTotsize);
  9879. // Begin postcall
  9880. if(RetVal == ERROR_SUCCESS)
  9881. {
  9882. dwOffset = 0;
  9883. for (i=0; i<num_vals; i++)
  9884. {
  9885. // Copy it all to start, a fallback scheme that NT uses. Notice
  9886. // that the only one we might change again is ve_valuelen, in
  9887. // the string types.
  9888. val_list[i].ve_valuelen = val_listA[i].ve_valuelen;
  9889. val_list[i].ve_type = val_listA[i].ve_type;
  9890. val_list[i].ve_valueptr = (DWORD_PTR)(lpValueBufA + dwOffset);
  9891. if ((val_list[i].ve_type == REG_SZ) ||
  9892. (val_list[i].ve_type == REG_EXPAND_SZ) ||
  9893. (val_list[i].ve_type == REG_MULTI_SZ))
  9894. {
  9895. // String-type values
  9896. cchValue = MultiByteToWideChar(g_acp,
  9897. 0,
  9898. (LPSTR)(lpValueBufA + val_listA[i].ve_valueptr),
  9899. val_listA[i].ve_valuelen,
  9900. (LPWSTR)lpValueBuf + dwOffset,
  9901. (*ldwTotsize - dwOffset));
  9902. // the length is whatever we copied. So update ve_valuelen
  9903. // and fix up the offset
  9904. val_list[i].ve_valuelen = cchValue;
  9905. dwOffset += cchValue;
  9906. }
  9907. else
  9908. {
  9909. // Non string-type values
  9910. CopyMemory((lpValueBuf + dwOffset),
  9911. (lpValueBufA + val_listA[i].ve_valueptr),
  9912. val_listA[i].ve_valuelen);
  9913. // fix up the offset
  9914. dwOffset += val_listA[i].ve_valuelen;
  9915. }
  9916. // Round dwOffset to DWORD boundaries? See BASE's regqmval.c for details
  9917. dwOffset = (dwOffset + sizeof(DWORD) - 1) & ~(sizeof(DWORD)-1);
  9918. }
  9919. }
  9920. else if(RetVal == ERROR_MORE_DATA)
  9921. {
  9922. // We need to thunk the Ansi required bytes back to Unicode. But
  9923. // there is not really any way to do this without having the data
  9924. // available. So just return the required bytes for the Ansi
  9925. // data (* 2 on non-DBCS), as this should always be enough.
  9926. if (ldwTotsize != NULL)
  9927. *ldwTotsize = (FDBCS_CPG(g_acp) ? *pdwTotsize : (*pdwTotsize * 2));
  9928. }
  9929. Cleanup:
  9930. if(rgszNames)
  9931. GodotHeapFree(rgszNames);
  9932. if(val_listA)
  9933. GodotHeapFree(val_listA);
  9934. if(lpValueBufA)
  9935. GodotHeapFree(lpValueBufA);
  9936. return RetVal;
  9937. }
  9938. End=
  9939. [EFunc]
  9940. TemplateName=RegQueryValueW
  9941. Begin=
  9942. LONG __stdcall
  9943. GodotRegQueryValueW(HKEY hKey, LPCWSTR lpSubKey, LPWSTR lpValue, PLONG lpcbValue)
  9944. {
  9945. // Begin locals
  9946. LONG RetVal;
  9947. LPSTR lpSubKeyAnsi;
  9948. LPSTR lpValueAnsi;
  9949. // Begin precall
  9950. GODOT_TO_ACP_STACKALLOC(lpSubKey, lpSubKeyAnsi);
  9951. _STACKALLOC((*lpcbValue*g_mcs)+1, lpValueAnsi);
  9952. if(!lpValueAnsi ||
  9953. (!lpSubKeyAnsi && lpSubKey))
  9954. {
  9955. return(ERROR_STACK_OVERFLOW);
  9956. }
  9957. RetVal=RegQueryValueA(hKey, lpSubKeyAnsi, lpValueAnsi, lpcbValue);
  9958. if(RetVal == ERROR_SUCCESS)
  9959. {
  9960. if(0 < MultiByteToWideChar(g_acp, 0, lpValueAnsi, -1, lpValue, *lpcbValue))
  9961. {
  9962. *lpcbValue = gwcslen(lpValue);
  9963. }
  9964. else
  9965. {
  9966. // The conversion failed for some reason, we assume due to an invalid buffer?
  9967. RetVal = ERROR_INSUFFICIENT_BUFFER;
  9968. }
  9969. }
  9970. // Finished
  9971. return RetVal;
  9972. }
  9973. End=
  9974. [EFunc]
  9975. TemplateName=RegQueryValueExW
  9976. Begin=
  9977. LONG __stdcall
  9978. GodotRegQueryValueExW( HKEY hKey,
  9979. LPCWSTR lpValueName,
  9980. LPDWORD lpReserved,
  9981. LPDWORD lpType,
  9982. LPBYTE lpData,
  9983. LPDWORD lpcbData
  9984. )
  9985. {
  9986. // Begin locals
  9987. LONG RetVal;
  9988. LPSTR lpValueNameAnsi;
  9989. DWORD dwType = 0;
  9990. DWORD cbData = 0;
  9991. // Begin precall
  9992. GODOT_TO_ACP_STACKALLOC(lpValueName, lpValueNameAnsi);
  9993. if(!lpValueNameAnsi && lpValueName)
  9994. return(ERROR_STACK_OVERFLOW);
  9995. // Ok, first call to get the type and size info
  9996. RetVal = RegQueryValueExA(hKey, lpValueNameAnsi, lpReserved, &dwType, NULL, &cbData);
  9997. if(lpType)
  9998. *lpType = dwType;
  9999. // Only do more work if they specified a buffer space; Note that
  10000. // the call we just made can only fail if the hKey is invalid or
  10001. // the value does not exist.
  10002. if((RetVal == ERROR_SUCCESS) && lpcbData)
  10003. {
  10004. switch(dwType)
  10005. {
  10006. case REG_SZ:
  10007. case REG_EXPAND_SZ:
  10008. case REG_MULTI_SZ:
  10009. {
  10010. LPSTR lpDataA;
  10011. DWORD cbNeeded;
  10012. // Alloc the space we need; Note that the call that filled
  10013. // cbData includes the terminating null character.
  10014. _STACKALLOC(cbData, lpDataA);
  10015. RetVal = RegQueryValueExA(hKey,
  10016. lpValueNameAnsi,
  10017. lpReserved,
  10018. &dwType,
  10019. (LPBYTE)lpDataA,
  10020. &cbData);
  10021. // Calc how many bytes we might need for a Unicode string.
  10022. // Note this might be an over-estimation in the DBCS case.
  10023. // CONSIDER: Perhaps we should just try to convert rather than
  10024. // guessing this way?
  10025. cbNeeded = ((cbData + 1) * sizeof(WCHAR));
  10026. if(cbNeeded > *lpcbData)
  10027. {
  10028. // If they passed a NULL buffer size, then we simply
  10029. // tell them we succeeded, otherwise we have to tell
  10030. // them there is more data
  10031. if(*lpcbData != 0)
  10032. RetVal = ERROR_MORE_DATA;
  10033. }
  10034. else if(lpData)
  10035. {
  10036. MultiByteToWideChar(g_acp, 0, lpDataA, cbData*g_mcs, (LPWSTR)lpData, cbData);
  10037. }
  10038. *lpcbData = cbNeeded;
  10039. break;
  10040. }
  10041. default:
  10042. // some non-string type of data, see if there is enough room;
  10043. // if there is, go for it (copy the length either way)
  10044. if(*lpcbData < cbData)
  10045. RetVal = ERROR_MORE_DATA;
  10046. else if(lpData)
  10047. RetVal = RegQueryValueExA(hKey, lpValueNameAnsi, lpReserved, lpType, lpData, lpcbData);
  10048. *lpcbData = cbData;
  10049. break;
  10050. }
  10051. }
  10052. // Finished
  10053. return RetVal;
  10054. }
  10055. End=
  10056. [EFunc]
  10057. TemplateName=RegisterClassW
  10058. Begin=
  10059. ATOM __stdcall
  10060. GodotRegisterClassW(const WNDCLASSW * lpWndClass)
  10061. {
  10062. // Begin locals
  10063. WNDCLASSA wca;
  10064. // Begin precall
  10065. ZeroMemory(&wca, sizeof(WNDCLASSA));
  10066. memcpy(&wca, lpWndClass, sizeof(UINT)+sizeof(WNDPROC)+2*sizeof(int)+4*sizeof(HANDLE));
  10067. GODOT_TO_ACP_STACKALLOC(lpWndClass->lpszMenuName, wca.lpszMenuName);
  10068. GODOT_TO_ACP_STACKALLOC(lpWndClass->lpszClassName, wca.lpszClassName);
  10069. // Call the 'A' version of the API
  10070. return(RegisterClassA(&wca));
  10071. }
  10072. End=
  10073. [EFunc]
  10074. TemplateName=RegisterClassExW
  10075. Begin=
  10076. ATOM __stdcall
  10077. GodotRegisterClassExW(const WNDCLASSEXW * lpwcx)
  10078. {
  10079. // Begin locals
  10080. WNDCLASSEXA wcxa;
  10081. // Begin precall
  10082. ZeroMemory(&wcxa, sizeof(WNDCLASSEXA));
  10083. memcpy(&wcxa, lpwcx, 2*sizeof(UINT)+sizeof(WNDPROC)+2*sizeof(int)+4*sizeof(HANDLE));
  10084. GODOT_TO_ACP_STACKALLOC(lpwcx->lpszMenuName, wcxa.lpszMenuName);
  10085. GODOT_TO_ACP_STACKALLOC(lpwcx->lpszClassName, wcxa.lpszClassName);
  10086. wcxa.hIconSm = lpwcx->hIconSm;
  10087. // Call the 'A' version of the API
  10088. return(RegisterClassExA(&wcxa));
  10089. }
  10090. End=
  10091. [EFunc]
  10092. TemplateName=RegSetValueExW
  10093. Begin=
  10094. LONG __stdcall
  10095. GodotRegSetValueExW( HKEY hKey,
  10096. LPCWSTR lpValueName,
  10097. DWORD Reserved,
  10098. DWORD dwType,
  10099. const BYTE * lpData,
  10100. DWORD cbData
  10101. )
  10102. {
  10103. // Begin locals
  10104. LONG RetVal;
  10105. LPSTR lpValueNameAnsi;
  10106. BYTE * lpDataAnsi = NULL;
  10107. size_t cchData;
  10108. // Begin precall
  10109. GODOT_TO_ACP_STACKALLOC(lpValueName, lpValueNameAnsi);
  10110. if(!lpValueNameAnsi && lpValueName)
  10111. return(ERROR_STACK_OVERFLOW);
  10112. switch (dwType)
  10113. {
  10114. case REG_MULTI_SZ:
  10115. case REG_SZ:
  10116. case REG_EXPAND_SZ:
  10117. {
  10118. size_t cbDataAnsi;
  10119. if (FSTRING_VALID((LPWSTR)lpData))
  10120. {
  10121. // Lets go for the minimal buffer we can reasonably get away with
  10122. if(dwType == REG_MULTI_SZ)
  10123. cchData = cchUnicodeMultiSz((LPWSTR)lpData) +1;
  10124. else
  10125. cchData = gwcslen((LPWSTR)lpData) + 1;
  10126. // Convert the information to ANSI and call the API with it
  10127. _STACKALLOC((cchData * g_mcs) + 1, lpDataAnsi);
  10128. if(lpDataAnsi==NULL)
  10129. {
  10130. return(ERROR_STACK_OVERFLOW);
  10131. }
  10132. ZeroMemory(lpDataAnsi, (cchData * g_mcs) + 1);
  10133. WideCharToMultiByte(g_acp, 0,
  10134. (LPWSTR)lpData, cchData,
  10135. (LPSTR)lpDataAnsi, (cchData * g_mcs),
  10136. NULL, NULL);
  10137. if(dwType == REG_MULTI_SZ)
  10138. cbDataAnsi = cbAnsiMultiSz((LPSTR)lpDataAnsi);
  10139. else
  10140. cbDataAnsi = lstrlenA((LPSTR)lpDataAnsi);
  10141. RetVal=RegSetValueExA(hKey,
  10142. lpValueNameAnsi,
  10143. Reserved,
  10144. dwType,
  10145. lpDataAnsi,
  10146. cbDataAnsi);
  10147. }
  10148. else
  10149. RetVal = ERROR_INVALID_PARAMETER;
  10150. break;
  10151. }
  10152. default:
  10153. {
  10154. // Unknown data, just call straight through.
  10155. RetVal=RegSetValueExA(hKey, lpValueNameAnsi, Reserved, dwType, lpData, cbData);
  10156. break;
  10157. }
  10158. }
  10159. // Finished
  10160. return RetVal;
  10161. }
  10162. End=
  10163. [EFunc]
  10164. TemplateName=RemoveDirectoryW
  10165. Begin=
  10166. BOOL __stdcall
  10167. GodotRemoveDirectoryW(LPCWSTR lpPathName)
  10168. {
  10169. LPSTR lpPathNameAnsi;
  10170. // Begin precall
  10171. GODOT_TO_CPG_STACKALLOC(lpPathName, lpPathNameAnsi, FILES_CPG, g_mcs);
  10172. if(lpPathNameAnsi==NULL)
  10173. {
  10174. return(FALSE);
  10175. }
  10176. return(RemoveDirectoryA(lpPathNameAnsi));
  10177. }
  10178. End=
  10179. [EFunc]
  10180. TemplateName=RemovePropA
  10181. Begin=
  10182. HANDLE __stdcall
  10183. GodotRemovePropA(HWND hWnd, LPCSTR lpString)
  10184. {
  10185. if(IsInternalWindowProperty((LPWSTR)lpString, FALSE))
  10186. return(0);
  10187. return(RemovePropA(hWnd, lpString));
  10188. }
  10189. End=
  10190. [EFunc]
  10191. TemplateName=RemovePropW
  10192. Begin=
  10193. HANDLE __stdcall
  10194. GodotRemovePropW(HWND hWnd, LPCWSTR lpString)
  10195. {
  10196. LPSTR lpStringAnsi;
  10197. if(IsInternalWindowProperty(lpString, TRUE))
  10198. return(0);
  10199. GODOT_TO_ACP_STACKALLOC(lpString, lpStringAnsi);
  10200. if(!lpStringAnsi && lpString)
  10201. return(0);
  10202. return(RemovePropA(hWnd, lpStringAnsi));
  10203. }
  10204. End=
  10205. [EFunc]
  10206. TemplateName=ReplaceTextW
  10207. Begin=
  10208. HWND __stdcall
  10209. GodotReplaceTextW(LPFINDREPLACEW lpfr)
  10210. {
  10211. return(FindReplaceTextHelper(lpfr, FALSE));
  10212. }
  10213. End=
  10214. [EFunc]
  10215. TemplateName=ResetDCW
  10216. Begin=
  10217. HDC __stdcall
  10218. GodotResetDCW(HDC hdc, DEVMODEW * lpInitData)
  10219. {
  10220. LPDEVMODEA lpdma;
  10221. _STACKALLOC(sizeof(DEVMODEA) + (lpInitData ? lpInitData->dmDriverExtra : 0), lpdma);
  10222. if(lpdma==NULL)
  10223. {
  10224. return(0);
  10225. }
  10226. ZeroMemory(lpdma, sizeof(DEVMODEA) + (lpInitData ? lpInitData->dmDriverExtra : 0));
  10227. if(lpInitData)
  10228. DevModeAfromW(lpdma, lpInitData);
  10229. return(ResetDCA(hdc, lpdma));
  10230. }
  10231. End=
  10232. [EFunc]
  10233. TemplateName=ResetPrinterW
  10234. Begin=
  10235. BOOL __stdcall
  10236. GodotResetPrinterW(HANDLE hPrinter, LPPRINTER_DEFAULTSW pDefault)
  10237. {
  10238. PRINTER_DEFAULTSA pda;
  10239. LPDEVMODEW lpdmW;
  10240. BOOL RetVal = FALSE;
  10241. // Begin precall
  10242. ZeroMemory(&pda, sizeof(PRINTER_DEFAULTSA));
  10243. lpdmW = pDefault->pDevMode;
  10244. pda.pDevMode = GodotHeapAlloc(sizeof(DEVMODEA) + lpdmW->dmDriverExtra);
  10245. if(pda.pDevMode)
  10246. {
  10247. ZeroMemory(pda.pDevMode, sizeof(DEVMODEA) + lpdmW->dmDriverExtra);
  10248. DevModeAfromW(pda.pDevMode, lpdmW);
  10249. GODOT_TO_ACP_STACKALLOC(pDefault->pDatatype, pda.pDatatype);
  10250. RetVal = ResetPrinterA(hPrinter, &pda);
  10251. GodotHeapFree(pda.pDevMode);
  10252. }
  10253. else
  10254. SetLastError(ERROR_OUTOFMEMORY);
  10255. return(RetVal);
  10256. }
  10257. End=
  10258. [EFunc]
  10259. TemplateName=SearchPathW
  10260. Begin=
  10261. DWORD __stdcall
  10262. GodotSearchPathW(LPCWSTR lpPath, LPCWSTR lpFileName, LPCWSTR lpExtension,
  10263. DWORD nBufferLength, LPWSTR lpBuffer, LPWSTR * lpFilePart)
  10264. {
  10265. // Begin locals
  10266. DWORD RetVal;
  10267. LPSTR lpPathAnsi;
  10268. LPSTR lpFileNameAnsi;
  10269. LPSTR lpExtensionAnsi;
  10270. LPSTR lpBufferAnsi;
  10271. UINT cpg = FILES_CPG;
  10272. // Begin precall
  10273. GODOT_TO_CPG_STACKALLOC(lpPath, lpPathAnsi, cpg, g_mcs);
  10274. GODOT_TO_CPG_STACKALLOC(lpFileName, lpFileNameAnsi, cpg, g_mcs);
  10275. GODOT_TO_CPG_STACKALLOC(lpExtension, lpExtensionAnsi, cpg, g_mcs);
  10276. _STACKALLOC((nBufferLength*g_mcs)+1, lpBufferAnsi);
  10277. RetVal=SearchPathA(lpPathAnsi,
  10278. lpFileNameAnsi,
  10279. lpExtensionAnsi,
  10280. nBufferLength*g_mcs,
  10281. lpBufferAnsi,
  10282. NULL);
  10283. if(RetVal)
  10284. {
  10285. MultiByteToWideChar(cpg, 0, lpBufferAnsi, nBufferLength*g_mcs, lpBuffer, nBufferLength);
  10286. if(lpFilePart)
  10287. {
  10288. WCHAR drive[_MAX_DRIVE];
  10289. WCHAR dir[_MAX_DIR];
  10290. // We do not bother with an ANSI version of lpFilePart and just derive it here
  10291. // (even non-technical folks like CWissink can contribute now and then!)
  10292. gwsplitpath(lpBuffer, drive, dir, NULL, NULL);
  10293. *lpFilePart = lpBuffer + gwcslen(drive) + gwcslen(dir);
  10294. }
  10295. }
  10296. // Finished
  10297. return RetVal;
  10298. }
  10299. End=
  10300. [EFunc]
  10301. TemplateName=SendDlgItemMessageW
  10302. Begin=
  10303. LRESULT __stdcall
  10304. GodotSendDlgItemMessageW(HWND hDlg, int nIDDlgItem, UINT Msg, WPARAM wParam, LPARAM lParam)
  10305. {
  10306. HWND hWnd = GetDlgItem(hDlg, nIDDlgItem);
  10307. // if the GetDlgItem fails, we will leave SetLastError alone (it
  10308. // will probably be ERROR_CONTROL_ID_NOT_FOUND anyway).
  10309. if (hWnd)
  10310. {
  10311. // Rather than going through SendDlgItemMessageA, we just
  10312. // do what the system does, and pretend we are SendMessage.
  10313. // Saves us some special casing in GodotTransmitMessage
  10314. return(GodotTransmitMessage(mtSendMessage, hWnd, Msg, wParam, lParam, 0, 0, 0, 0, 0, 0));
  10315. }
  10316. return(0);
  10317. }
  10318. End=
  10319. [EFunc]
  10320. TemplateName=SendMessageW
  10321. Begin=
  10322. LRESULT __stdcall
  10323. GodotSendMessageW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  10324. {
  10325. return(GodotTransmitMessage(mtSendMessage, hWnd, Msg, wParam, lParam, 0, 0, 0, 0, 0, 0));
  10326. }
  10327. End=
  10328. [EFunc]
  10329. TemplateName=SendMessageCallbackW
  10330. Begin=
  10331. BOOL __stdcall
  10332. GodotSendMessageCallbackW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam,
  10333. SENDASYNCPROC lpResultCallBack, ULONG_PTR dwData)
  10334. {
  10335. return(GodotTransmitMessage(mtSendMessageCallback, hWnd, Msg, wParam, lParam,
  10336. 0, lpResultCallBack, dwData, 0, 0, 0));
  10337. }
  10338. End=
  10339. [EFunc]
  10340. TemplateName=SendMessageTimeoutW
  10341. Begin=
  10342. LRESULT __stdcall
  10343. GodotSendMessageTimeoutW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam,
  10344. UINT fuFlags, UINT uTimeout, PDWORD_PTR lpdwResult)
  10345. {
  10346. return(GodotTransmitMessage(mtSendMessageTimeout, hWnd, Msg, wParam, lParam,
  10347. 0, 0, 0, fuFlags, uTimeout, lpdwResult));
  10348. }
  10349. End=
  10350. [EFunc]
  10351. TemplateName=SendNotifyMessageW
  10352. Begin=
  10353. BOOL __stdcall
  10354. GodotSendNotifyMessageW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  10355. {
  10356. return(GodotTransmitMessage(mtSendNotifyMessage, hWnd, Msg, wParam, lParam, 0, 0, 0, 0, 0, 0));
  10357. }
  10358. End=
  10359. [EFunc]
  10360. TemplateName=SetCalendarInfoW
  10361. Begin=
  10362. BOOL __stdcall
  10363. GodotSetCalendarInfoW(LCID Locale, CALID Calendar, CALTYPE CalType, LPCWSTR lpCalData)
  10364. {
  10365. if (s_pfnSetCalendarInfoA == NULL)
  10366. {
  10367. // Must allocate stuff for this API call
  10368. s_pfnSetCalendarInfoA = (PFNscia)GetKernelProc("SetCalendarInfoA");
  10369. }
  10370. if (s_pfnSetCalendarInfoA)
  10371. {
  10372. LPSTR lpCalDataAnsi;
  10373. UINT cpg;
  10374. UINT mcs;
  10375. if(CalType & CAL_USE_CP_ACP)
  10376. {
  10377. cpg = g_acp;
  10378. mcs = g_mcs;
  10379. }
  10380. else
  10381. {
  10382. cpg = CpgFromLocale(Locale);
  10383. mcs = CbPerChOfCpg(cpg);
  10384. }
  10385. GODOT_TO_CPG_STACKALLOC(lpCalData, lpCalDataAnsi, cpg, mcs);
  10386. return((s_pfnSetCalendarInfoA (Locale, Calendar, CalType, lpCalDataAnsi)));
  10387. }
  10388. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  10389. return FALSE;
  10390. }
  10391. End=
  10392. [EFunc]
  10393. TemplateName=SetClassLongW
  10394. Begin=
  10395. DWORD __stdcall
  10396. GodotSetClassLongW(HWND hWnd, int nIndex, LONG dwNewLong)
  10397. {
  10398. DWORD RetVal;
  10399. if(nIndex != GCL_MENUNAME)
  10400. RetVal=SetClassLongA(hWnd, nIndex, dwNewLong);
  10401. else
  10402. {
  10403. LPSTR szNewLong;
  10404. GODOT_TO_ACP_STACKALLOC(dwNewLong, szNewLong);
  10405. RetVal=SetClassLongA(hWnd, nIndex, (DWORD)szNewLong);
  10406. if(RetVal)
  10407. {
  10408. // We need to convert this string to Unicode and stick it in
  10409. // our global buffer, then return the pointer to that buffer.
  10410. // See comments at the dec. of m_wzMenuName for why things
  10411. // have to be done this way.
  10412. MultiByteToWideChar(g_acp, 0, (LPSTR)RetVal, -1, m_wzMenuName, 256);
  10413. RetVal = (DWORD)m_wzMenuName;
  10414. }
  10415. }
  10416. return RetVal;
  10417. }
  10418. End=
  10419. [EFunc]
  10420. TemplateName=SetConsoleTitleW
  10421. Begin=
  10422. BOOL __stdcall GodotSetConsoleTitleW(LPCWSTR lpConsoleTitle)
  10423. {
  10424. LPSTR lpConsoleTitleAnsi;
  10425. GODOT_TO_CPG_STACKALLOC(lpConsoleTitle, lpConsoleTitleAnsi, g_oemcp, g_mcs);
  10426. return(SetConsoleTitleA(lpConsoleTitleAnsi));
  10427. }
  10428. End=
  10429. [EFunc]
  10430. TemplateName=SetCurrentDirectoryW
  10431. Begin=
  10432. BOOL __stdcall
  10433. GodotSetCurrentDirectoryW(LPCWSTR lpPathName)
  10434. {
  10435. LPSTR lpPathNameAnsi;
  10436. // Begin precall
  10437. GODOT_TO_CPG_STACKALLOC(lpPathName, lpPathNameAnsi, FILES_CPG, g_mcs);
  10438. return(SetCurrentDirectoryA(lpPathNameAnsi));
  10439. }
  10440. End=
  10441. [EFunc]
  10442. TemplateName=SetJobW
  10443. Begin=
  10444. BOOL __stdcall
  10445. GodotSetJobW(HANDLE hPrinter, DWORD JobId, DWORD Level, LPBYTE pJob, DWORD Command)
  10446. {
  10447. switch(Level)
  10448. {
  10449. case 0:
  10450. return(SetJobA(hPrinter, JobId, Level, pJob, Command));
  10451. break;
  10452. case 1:
  10453. {
  10454. JOB_INFO_1A ji1a;
  10455. LPJOB_INFO_1W lpji1 = (LPJOB_INFO_1W)pJob;
  10456. ji1a.JobId = lpji1->JobId;
  10457. GODOT_TO_ACP_STACKALLOC(lpji1->pPrinterName, ji1a.pPrinterName);
  10458. GODOT_TO_ACP_STACKALLOC(lpji1->pMachineName, ji1a.pMachineName);
  10459. GODOT_TO_ACP_STACKALLOC(lpji1->pUserName, ji1a.pUserName);
  10460. GODOT_TO_ACP_STACKALLOC(lpji1->pDocument, ji1a.pDocument);
  10461. GODOT_TO_ACP_STACKALLOC(lpji1->pDatatype, ji1a.pDatatype);
  10462. GODOT_TO_ACP_STACKALLOC(lpji1->pStatus, ji1a.pStatus);
  10463. ji1a.Status = lpji1->Status;
  10464. ji1a.Priority = lpji1->Priority;
  10465. ji1a.Position = lpji1->Position;
  10466. ji1a.TotalPages = lpji1->TotalPages;
  10467. ji1a.PagesPrinted = lpji1->PagesPrinted;
  10468. ji1a.Submitted = lpji1->Submitted;
  10469. return(SetJobA(hPrinter, JobId, Level, (LPBYTE)&ji1a, Command));
  10470. }
  10471. case 2:
  10472. {
  10473. JOB_INFO_2A ji2a;
  10474. LPJOB_INFO_2W lpji2 = (LPJOB_INFO_2W)pJob;
  10475. BOOL RetVal = FALSE;
  10476. ji2a.JobId = lpji2->JobId;
  10477. GODOT_TO_ACP_STACKALLOC(lpji2->pPrinterName, ji2a.pPrinterName);
  10478. GODOT_TO_ACP_STACKALLOC(lpji2->pMachineName, ji2a.pMachineName);
  10479. GODOT_TO_ACP_STACKALLOC(lpji2->pUserName, ji2a.pUserName);
  10480. GODOT_TO_ACP_STACKALLOC(lpji2->pNotifyName, ji2a.pNotifyName);
  10481. GODOT_TO_ACP_STACKALLOC(lpji2->pDocument, ji2a.pDocument);
  10482. GODOT_TO_ACP_STACKALLOC(lpji2->pDatatype, ji2a.pDatatype);
  10483. GODOT_TO_ACP_STACKALLOC(lpji2->pPrintProcessor, ji2a.pPrintProcessor);
  10484. GODOT_TO_ACP_STACKALLOC(lpji2->pParameters, ji2a.pParameters);
  10485. GODOT_TO_ACP_STACKALLOC(lpji2->pDriverName, ji2a.pDriverName);
  10486. GODOT_TO_ACP_STACKALLOC(lpji2->pStatus, ji2a.pStatus);
  10487. ji2a.pSecurityDescriptor = lpji2->pSecurityDescriptor;
  10488. ji2a.Status = lpji2->Status;
  10489. ji2a.Priority = lpji2->Priority;
  10490. ji2a.Position = lpji2->Position;
  10491. ji2a.StartTime = lpji2->StartTime;
  10492. ji2a.UntilTime = lpji2->UntilTime;
  10493. ji2a.TotalPages = lpji2->TotalPages;
  10494. ji2a.Size = lpji2->Size;
  10495. ji2a.Submitted = lpji2->Submitted;
  10496. ji2a.Time = lpji2->Time;
  10497. ji2a.PagesPrinted = lpji2->PagesPrinted;
  10498. if(lpji2->pDevMode)
  10499. {
  10500. ji2a.pDevMode = GodotHeapAlloc(sizeof(DEVMODEA) + lpji2->pDevMode->dmDriverExtra);
  10501. if(ji2a.pDevMode==NULL)
  10502. {
  10503. SetLastError(ERROR_OUTOFMEMORY);
  10504. return(FALSE);
  10505. }
  10506. ZeroMemory(ji2a.pDevMode, sizeof(DEVMODEA) + lpji2->pDevMode->dmDriverExtra);
  10507. DevModeAfromW(ji2a.pDevMode, lpji2->pDevMode);
  10508. }
  10509. RetVal = SetJobA(hPrinter, JobId, Level, (LPBYTE)&ji2a, Command);
  10510. if(lpji2->pDevMode && ji2a.pDevMode)
  10511. GodotHeapFree(ji2a.pDevMode);
  10512. return(RetVal);
  10513. break;
  10514. }
  10515. default:
  10516. {
  10517. SetLastError(ERROR_INVALID_PARAMETER);
  10518. return(FALSE);
  10519. break;
  10520. }
  10521. }
  10522. }
  10523. End=
  10524. [EFunc]
  10525. TemplateName=SetLocaleInfoW
  10526. Begin=
  10527. BOOL __stdcall
  10528. GodotSetLocaleInfoW(LCID Locale, LCTYPE LCType, LPCWSTR lpLCData)
  10529. {
  10530. LPSTR lpLCDataAnsi;
  10531. UINT cpg;
  10532. UINT mcs;
  10533. // Begin precall
  10534. if (LCType & LOCALE_USE_CP_ACP)
  10535. {
  10536. // Win9x accepts LOCALE_USE_CP_ACP, so we need to treat the
  10537. // flag properly and use it for any/all mapping if the user
  10538. // requests it.
  10539. cpg = g_acp;
  10540. mcs = g_mcs;
  10541. }
  10542. else
  10543. {
  10544. cpg = CpgFromLocale(Locale);
  10545. mcs = CbPerChOfCpg(cpg);
  10546. }
  10547. GODOT_TO_CPG_STACKALLOC(lpLCData, lpLCDataAnsi, cpg, mcs);
  10548. if(lpLCDataAnsi==NULL)
  10549. {
  10550. return(FALSE);
  10551. }
  10552. return(SetLocaleInfoA(Locale, LCType, lpLCDataAnsi));
  10553. }
  10554. End=
  10555. [EFunc]
  10556. TemplateName=SetMenuItemInfoW
  10557. Begin=
  10558. BOOL __stdcall
  10559. GodotSetMenuItemInfoW(HMENU hMenu, UINT uItem, BOOL fByPosition, LPCMENUITEMINFOW lpmiiw)
  10560. {
  10561. MENUITEMINFOA miia;
  10562. BOOL RetVal;
  10563. BOOL fAlloc = MenuItemInfoAfromW(&miia, lpmiiw);
  10564. RetVal = SetMenuItemInfoA(hMenu, uItem, fByPosition, &miia);
  10565. if(fAlloc)
  10566. GodotHeapFree(miia.dwTypeData);
  10567. return(RetVal);
  10568. }
  10569. End=
  10570. [EFunc]
  10571. TemplateName=SetPrinterW
  10572. Begin=
  10573. BOOL __stdcall
  10574. GodotSetPrinterW(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, DWORD Command)
  10575. {
  10576. switch(Level)
  10577. {
  10578. case 0:
  10579. {
  10580. return(SetPrinterA(hPrinter, Level, pPrinter, Command));
  10581. break;
  10582. }
  10583. case 2:
  10584. {
  10585. PRINTER_INFO_2A pi2a;
  10586. LPPRINTER_INFO_2W lppi2 = (LPPRINTER_INFO_2W)pPrinter;
  10587. BOOL RetVal = FALSE;
  10588. GODOT_TO_ACP_STACKALLOC(lppi2->pServerName, pi2a.pServerName);
  10589. GODOT_TO_ACP_STACKALLOC(lppi2->pPrinterName, pi2a.pPrinterName);
  10590. GODOT_TO_ACP_STACKALLOC(lppi2->pShareName, pi2a.pShareName);
  10591. GODOT_TO_ACP_STACKALLOC(lppi2->pPortName, pi2a.pPortName);
  10592. GODOT_TO_ACP_STACKALLOC(lppi2->pDriverName, pi2a.pDriverName);
  10593. GODOT_TO_ACP_STACKALLOC(lppi2->pComment, pi2a.pComment);
  10594. GODOT_TO_ACP_STACKALLOC(lppi2->pLocation, pi2a.pLocation);
  10595. if((!pi2a.pServerName && lppi2->pServerName) ||
  10596. (!pi2a.pPrinterName && lppi2->pPrinterName) ||
  10597. (!pi2a.pShareName && lppi2->pShareName) ||
  10598. (!pi2a.pPortName && lppi2->pPortName) ||
  10599. (!pi2a.pDriverName && lppi2->pDriverName) ||
  10600. (!pi2a.pComment && lppi2->pComment) ||
  10601. (!pi2a.pLocation && lppi2->pLocation))
  10602. {
  10603. return(FALSE);
  10604. }
  10605. GODOT_TO_ACP_STACKALLOC(lppi2->pSepFile, pi2a.pSepFile);
  10606. GODOT_TO_ACP_STACKALLOC(lppi2->pPrintProcessor, pi2a.pPrintProcessor);
  10607. GODOT_TO_ACP_STACKALLOC(lppi2->pDatatype, pi2a.pDatatype);
  10608. GODOT_TO_ACP_STACKALLOC(lppi2->pParameters, pi2a.pParameters);
  10609. if((!pi2a.pSepFile && lppi2->pSepFile) ||
  10610. (!pi2a.pPrintProcessor && lppi2->pPrintProcessor) ||
  10611. (!pi2a.pDatatype && lppi2->pDatatype) ||
  10612. (!pi2a.pParameters && lppi2->pParameters))
  10613. {
  10614. return(FALSE);
  10615. }
  10616. pi2a.pSecurityDescriptor = lppi2->pSecurityDescriptor;
  10617. pi2a.Attributes = lppi2->Attributes;
  10618. pi2a.Priority = lppi2->Priority;
  10619. pi2a.DefaultPriority = lppi2->DefaultPriority;
  10620. pi2a.StartTime = lppi2->StartTime;
  10621. pi2a.UntilTime = lppi2->UntilTime;
  10622. pi2a.Status = lppi2->Status;
  10623. pi2a.cJobs = lppi2->cJobs;
  10624. pi2a.AveragePPM = lppi2->AveragePPM;
  10625. if(lppi2->pDevMode)
  10626. {
  10627. pi2a.pDevMode = GodotHeapAlloc(sizeof(DEVMODEA) + lppi2->pDevMode->dmDriverExtra);
  10628. if(pi2a.pDevMode==NULL)
  10629. {
  10630. SetLastError(ERROR_OUTOFMEMORY);
  10631. return(FALSE);
  10632. }
  10633. ZeroMemory(pi2a.pDevMode, sizeof(DEVMODEA) + lppi2->pDevMode->dmDriverExtra);
  10634. DevModeAfromW(pi2a.pDevMode, lppi2->pDevMode);
  10635. }
  10636. RetVal = SetPrinterA(hPrinter, Level, (LPBYTE)&pi2a, Command);
  10637. if(lppi2->pDevMode && pi2a.pDevMode)
  10638. GodotHeapFree(pi2a.pDevMode);
  10639. return(RetVal);
  10640. break;
  10641. }
  10642. case 5:
  10643. {
  10644. PRINTER_INFO_5A pi5a;
  10645. LPPRINTER_INFO_5W lppi5 = (LPPRINTER_INFO_5W)pPrinter;
  10646. GODOT_TO_ACP_STACKALLOC(lppi5->pPrinterName, pi5a.pPrinterName);
  10647. GODOT_TO_ACP_STACKALLOC(lppi5->pPortName, pi5a.pPortName);
  10648. if((!pi5a.pPrinterName && lppi5->pPrinterName) ||
  10649. (!pi5a.pPortName && lppi5->pPortName))
  10650. {
  10651. return(FALSE);
  10652. }
  10653. pi5a.Attributes = lppi5->Attributes;
  10654. pi5a.DeviceNotSelectedTimeout = lppi5->DeviceNotSelectedTimeout;
  10655. pi5a.TransmissionRetryTimeout = lppi5->TransmissionRetryTimeout;
  10656. return(SetPrinterA(hPrinter, Level, (LPBYTE)&pi5a, Command));
  10657. break;
  10658. }
  10659. default:
  10660. {
  10661. SetLastError(ERROR_INVALID_PARAMETER);
  10662. return(FALSE);
  10663. break;
  10664. }
  10665. }
  10666. }
  10667. End=
  10668. [EFunc]
  10669. TemplateName=SetPrinterDataW
  10670. Begin=
  10671. DWORD __stdcall
  10672. GodotSetPrinterDataW(HANDLE hPrinter, LPWSTR pValueName, DWORD Type, LPBYTE pData, DWORD cbData)
  10673. {
  10674. LPSTR pValueNameAnsi;
  10675. LPSTR pDataAnsi;
  10676. size_t cchData;
  10677. GODOT_TO_ACP_STACKALLOC(pValueName, pValueNameAnsi);
  10678. if(!pValueNameAnsi && pValueName)
  10679. return(0);
  10680. switch(Type)
  10681. {
  10682. case REG_MULTI_SZ:
  10683. if (FSTRING_VALID((LPWSTR)pData))
  10684. {
  10685. // Lets go for the minimal buffer we can reasonably get away with
  10686. cchData = gwcslen((LPWSTR)pData);
  10687. // Convert the information to ANSI and call the API with it
  10688. _STACKALLOC((cchData * g_mcs) + 1, pDataAnsi);
  10689. if(!pDataAnsi)
  10690. {
  10691. return(ERROR_STACK_OVERFLOW);
  10692. }
  10693. ZeroMemory(pDataAnsi, (cchData * g_mcs) + 1);
  10694. WideCharToMultiByte(g_acp,
  10695. 0,
  10696. (LPWSTR)pData,
  10697. (cbData / sizeof(WCHAR)),
  10698. pDataAnsi,
  10699. (cchData * g_mcs) + 1,
  10700. NULL,
  10701. NULL);
  10702. }
  10703. else
  10704. pDataAnsi = (LPSTR)pData;
  10705. return(SetPrinterDataA(hPrinter,
  10706. pValueNameAnsi,
  10707. Type,
  10708. (LPBYTE)pDataAnsi,
  10709. lstrlenA(pDataAnsi)));
  10710. break;
  10711. case REG_SZ:
  10712. case REG_EXPAND_SZ:
  10713. if (FSTRING_VALID((LPWSTR)pData))
  10714. {
  10715. // Lets go for the minimal buffer we can reasonably get away with
  10716. cchData = cchUnicodeMultiSz((LPWSTR)pData);
  10717. // Convert the information to ANSI and call the API with it
  10718. _STACKALLOC((cchData * g_mcs) + 1, pDataAnsi);
  10719. if(pDataAnsi==NULL)
  10720. {
  10721. return(0);
  10722. }
  10723. WideCharToMultiByte(g_acp, 0,
  10724. (LPWSTR)pData, (cbData / sizeof(WCHAR)),
  10725. (LPSTR)pDataAnsi, (cchData * g_mcs),
  10726. NULL, NULL);
  10727. }
  10728. else
  10729. pDataAnsi = (LPSTR)pData;
  10730. return(SetPrinterDataA(hPrinter, pValueNameAnsi, Type,
  10731. (LPBYTE)pDataAnsi, cbAnsiMultiSz(pDataAnsi)));
  10732. break;
  10733. default:
  10734. return(SetPrinterDataA(hPrinter, pValueNameAnsi, Type, pData, cbData));
  10735. break;
  10736. }
  10737. }
  10738. End=
  10739. [EFunc]
  10740. TemplateName=SetPropA
  10741. Begin=
  10742. BOOL __stdcall
  10743. GodotSetPropA(HWND hWnd, LPCSTR lpString, HANDLE hData)
  10744. {
  10745. if(IsInternalWindowProperty((LPWSTR)lpString, FALSE))
  10746. return(FALSE);
  10747. return(SetPropA(hWnd, lpString, hData));
  10748. }
  10749. End=
  10750. [EFunc]
  10751. TemplateName=SetPropW
  10752. Begin=
  10753. BOOL __stdcall
  10754. GodotSetPropW(HWND hWnd, LPCWSTR lpString, HANDLE hData)
  10755. {
  10756. LPSTR lpStringAnsi;
  10757. if(IsInternalWindowProperty(lpString, TRUE))
  10758. return(FALSE);
  10759. GODOT_TO_ACP_STACKALLOC(lpString, lpStringAnsi);
  10760. if(!lpStringAnsi && lpString)
  10761. return(0);
  10762. return(SetPropA(hWnd, lpStringAnsi, hData));
  10763. }
  10764. End=
  10765. [EFunc]
  10766. TemplateName=SetVolumeLabelW
  10767. Begin=
  10768. BOOL __stdcall
  10769. GodotSetVolumeLabelW(LPCWSTR lpRootPathName, LPCWSTR lpVolumeName)
  10770. {
  10771. LPSTR lpRootPathNameAnsi;
  10772. LPSTR lpVolumeNameAnsi;
  10773. UINT cpg = FILES_CPG;
  10774. // Begin precall
  10775. GODOT_TO_CPG_STACKALLOC(lpRootPathName, lpRootPathNameAnsi, cpg, g_mcs);
  10776. GODOT_TO_CPG_STACKALLOC(lpVolumeName, lpVolumeNameAnsi, cpg, g_mcs);
  10777. return(SetVolumeLabelA(lpRootPathNameAnsi, lpVolumeNameAnsi));
  10778. }
  10779. End=
  10780. [EFunc]
  10781. TemplateName=SetWindowsHookA
  10782. Begin=
  10783. HHOOK __stdcall
  10784. GodotSetWindowsHookA(int nFilterType, HOOKPROC pfnFilterProc)
  10785. {
  10786. // CONSIDER: Support Hook functions? This is a tough one!
  10787. // This [EFunc] is not even hooked up at the moment.
  10788. return(SetWindowsHookA(nFilterType, pfnFilterProc));
  10789. }
  10790. End=
  10791. [EFunc]
  10792. TemplateName=SetWindowsHookW
  10793. Begin=
  10794. HHOOK __stdcall
  10795. GodotSetWindowsHookW(int nFilterType, HOOKPROC pfnFilterProc)
  10796. {
  10797. // CONSIDER: Support Hook functions? This is a tough one!
  10798. return(SetWindowsHookA(nFilterType, pfnFilterProc));
  10799. }
  10800. End=
  10801. [EFunc]
  10802. TemplateName=SetWindowsHookExA
  10803. Begin=
  10804. HHOOK __stdcall
  10805. GodotSetWindowsHookExA(int idHook, HOOKPROC lpfn, HINSTANCE hmod, DWORD dwThreadId)
  10806. {
  10807. // CONSIDER: Support Hook functions? This is a tough one!
  10808. // This [EFunc] is not even hooked up at the moment.
  10809. return(SetWindowsHookExA(idHook, lpfn, hmod, dwThreadId));
  10810. }
  10811. End=
  10812. [EFunc]
  10813. TemplateName=SetWindowsHookExW
  10814. Begin=
  10815. HHOOK __stdcall
  10816. GodotSetWindowsHookExW(int idHook, HOOKPROC lpfn, HINSTANCE hmod, DWORD dwThreadId)
  10817. {
  10818. // CONSIDER: Support Hook functions? This is a tough one!
  10819. return(SetWindowsHookExA(idHook, lpfn, hmod, dwThreadId));
  10820. }
  10821. End=
  10822. [EFunc]
  10823. TemplateName=SetWindowLongA
  10824. Begin=
  10825. LONG __stdcall
  10826. GodotSetWindowLongA(HWND hWnd, int nIndex, LONG dwNewLong)
  10827. {
  10828. return(SetWindowLongInternal(hWnd, nIndex, dwNewLong, FALSE));
  10829. }
  10830. End=
  10831. [EFunc]
  10832. TemplateName=SetWindowLongW
  10833. Begin=
  10834. LONG __stdcall
  10835. GodotSetWindowLongW(HWND hWnd, int nIndex, LONG dwNewLong)
  10836. {
  10837. return(SetWindowLongInternal(hWnd, nIndex, dwNewLong, TRUE));
  10838. }
  10839. End=
  10840. [EFunc]
  10841. TemplateName=SetWindowTextW
  10842. Begin=
  10843. BOOL __stdcall
  10844. GodotSetWindowTextW(HWND hWnd, LPCWSTR lpString)
  10845. {
  10846. BOOL RetVal;
  10847. LPSTR lpStringAnsi = NULL;
  10848. ALLOCRETURN ar = GodotToAcpOnHeap(lpString, &lpStringAnsi);
  10849. if(ar==arFailed)
  10850. RetVal = FALSE;
  10851. else
  10852. RetVal = SetWindowTextA(hWnd, lpStringAnsi);
  10853. if(ar==arAlloc)
  10854. GodotHeapFree(lpStringAnsi);
  10855. return(RetVal);
  10856. }
  10857. End=
  10858. [EFunc]
  10859. TemplateName=ShellAboutW
  10860. Begin=
  10861. INT __stdcall
  10862. GodotShellAboutW(HWND hWnd, LPCWSTR szApp, LPCWSTR szOtherStuff, HICON hIcon)
  10863. {
  10864. LPSTR szAppAnsi;
  10865. LPSTR szOtherStuffAnsi;
  10866. GODOT_TO_ACP_STACKALLOC(szApp, szAppAnsi);
  10867. GODOT_TO_ACP_STACKALLOC(szOtherStuff, szOtherStuffAnsi);
  10868. if((!szAppAnsi && szApp) ||
  10869. (!szOtherStuffAnsi && szOtherStuff))
  10870. return(0);
  10871. return(ShellAboutA(hWnd, szAppAnsi, szOtherStuffAnsi, hIcon));
  10872. }
  10873. End=
  10874. [EFunc]
  10875. TemplateName=SHChangeNotify
  10876. Begin=
  10877. // uFlags & SHCNF_TYPE is an ID which indicates what dwItem1 and dwItem2 mean
  10878. #define SHCNF_IDLIST 0x0000 // LPITEMIDLIST
  10879. #define SHCNF_PATHA 0x0001 // path name
  10880. #define SHCNF_PRINTERA 0x0002 // printer friendly name
  10881. #define SHCNF_DWORD 0x0003 // DWORD
  10882. #define SHCNF_PRINTJOBA 0x0004 // dwItem1: printer name
  10883. // dwItem2: SHCNF_PRINTJOB_DATA
  10884. #define SHCNF_PATHW 0x0005 // path name
  10885. #define SHCNF_PRINTERW 0x0006 // printer friendly name
  10886. #define SHCNF_PRINTJOBW 0x0007 // dwItem1: printer name
  10887. // dwItem2: SHCNF_PRINTJOB_DATA
  10888. #define SHCNF_TYPE 0x00FF
  10889. #define SHCNF_FLUSH 0x1000
  10890. #define SHCNF_FLUSHNOWAIT 0x2000
  10891. #define SHCNF_HAS_WSTR_PARAMS(f) ((f & SHCNF_TYPE) == SHCNF_PATHW || \
  10892. (f & SHCNF_TYPE) == SHCNF_PRINTERW || \
  10893. (f & SHCNF_TYPE) == SHCNF_PRINTJOBW )
  10894. void __stdcall
  10895. GodotSHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
  10896. {
  10897. if(!SHCNF_HAS_WSTR_PARAMS(uFlags))
  10898. {
  10899. SHChangeNotify(wEventId, uFlags, dwItem1, dwItem2);
  10900. }
  10901. else
  10902. {
  10903. LPSTR dwItem1Ansi, dwItem2Ansi;
  10904. GODOT_TO_ACP_STACKALLOC(dwItem1, dwItem1Ansi);
  10905. GODOT_TO_ACP_STACKALLOC(dwItem2, dwItem2Ansi);
  10906. // Munge flags to ANSI types based on
  10907. // the Unicode types that are there now
  10908. if ((uFlags & SHCNF_TYPE) == SHCNF_PATHW)
  10909. {
  10910. uFlags = (uFlags & ~SHCNF_TYPE) | SHCNF_PATHA;
  10911. }
  10912. else if ((uFlags & SHCNF_TYPE) == SHCNF_PRINTERW)
  10913. {
  10914. uFlags = (uFlags & ~SHCNF_TYPE) | SHCNF_PRINTERA;
  10915. }
  10916. else
  10917. {
  10918. uFlags = (uFlags & ~SHCNF_TYPE) | SHCNF_PRINTJOBA;
  10919. }
  10920. SHChangeNotify(wEventId, uFlags, (void*)dwItem1Ansi, (void*)dwItem2Ansi);
  10921. }
  10922. return ;
  10923. }
  10924. End=
  10925. [EFunc]
  10926. TemplateName=ShellExecuteW
  10927. Begin=
  10928. HINSTANCE __stdcall
  10929. GodotShellExecuteW( HWND hwnd,
  10930. LPCWSTR lpOperation,
  10931. LPCWSTR lpFile,
  10932. LPCWSTR lpParameters,
  10933. LPCWSTR lpDirectory,
  10934. INT nShowCmd
  10935. )
  10936. {
  10937. LPSTR lpOperationAnsi, lpFileAnsi, lpParametersAnsi, lpDirectoryAnsi;
  10938. GODOT_TO_ACP_STACKALLOC(lpOperation, lpOperationAnsi);
  10939. GODOT_TO_ACP_STACKALLOC(lpFile, lpFileAnsi);
  10940. GODOT_TO_ACP_STACKALLOC(lpParameters, lpParametersAnsi);
  10941. GODOT_TO_ACP_STACKALLOC(lpDirectory, lpDirectoryAnsi);
  10942. if((!lpOperationAnsi && lpOperation) ||
  10943. (!lpFileAnsi && lpFile) ||
  10944. (!lpParametersAnsi && lpParameters) ||
  10945. (!lpDirectoryAnsi && lpDirectory))
  10946. return(0);
  10947. return(ShellExecuteA(hwnd, lpOperationAnsi, lpFileAnsi, lpParametersAnsi, lpDirectoryAnsi, nShowCmd));
  10948. }
  10949. End=
  10950. [EFunc]
  10951. TemplateName=ShellExecuteExW
  10952. Begin=
  10953. BOOL __stdcall
  10954. GodotShellExecuteExW(LPSHELLEXECUTEINFOW lpsei)
  10955. {
  10956. SHELLEXECUTEINFOA seia;
  10957. size_t lpFileLength;
  10958. BOOL RetVal;
  10959. ZeroMemory(&seia, sizeof(SHELLEXECUTEINFOA));
  10960. seia.cbSize = sizeof(SHELLEXECUTEINFOA);
  10961. seia.fMask = lpsei->fMask;
  10962. seia.hwnd = lpsei->hwnd;
  10963. seia.nShow = lpsei->nShow;
  10964. seia.hInstApp = lpsei->hInstApp;
  10965. seia.lpIDList = lpsei->lpIDList;
  10966. seia.hkeyClass = lpsei->hkeyClass;
  10967. seia.dwHotKey = lpsei->dwHotKey;
  10968. seia.hIcon = lpsei->hIcon;
  10969. seia.hProcess = lpsei->hProcess;
  10970. lpFileLength = cchUnicodeMultiSz(lpsei->lpFile);
  10971. _STACKALLOC(lpFileLength, seia.lpFile);
  10972. GODOT_TO_ACP_STACKALLOC(lpsei->lpVerb, seia.lpVerb);
  10973. GODOT_TO_ACP_STACKALLOC(lpsei->lpParameters, seia.lpParameters);
  10974. GODOT_TO_ACP_STACKALLOC(lpsei->lpDirectory, seia.lpDirectory);
  10975. GODOT_TO_ACP_STACKALLOC(lpsei->lpClass, seia.lpClass);
  10976. WideCharToMultiByte(g_acp, 0,
  10977. lpsei->lpFile, lpFileLength,
  10978. (LPSTR)(seia.lpFile), lpFileLength,
  10979. NULL, NULL);
  10980. RetVal = ShellExecuteExA(&seia);
  10981. lpsei->hInstApp = seia.hInstApp;
  10982. lpsei->hProcess = seia.hProcess;
  10983. return RetVal;
  10984. }
  10985. End=
  10986. [EFunc]
  10987. TemplateName=Shell_NotifyIconW
  10988. Begin=
  10989. BOOL __stdcall
  10990. GodotShell_NotifyIconW(DWORD dwMessage, PNOTIFYICONDATAW lpData)
  10991. {
  10992. PNOTIFYICONDATAA pnida;
  10993. if (lpData->cbSize == (UINT)NOTIFYICONDATAW_V1_SIZE)
  10994. {
  10995. // Old structure
  10996. _STACKALLOC(NOTIFYICONDATAA_V1_SIZE, pnida);
  10997. if(pnida)
  10998. {
  10999. ZeroMemory(pnida, NOTIFYICONDATAA_V1_SIZE);
  11000. pnida->cbSize = NOTIFYICONDATAA_V1_SIZE;
  11001. }
  11002. }
  11003. else
  11004. {
  11005. // New structure
  11006. _STACKALLOC(sizeof(NOTIFYICONDATA), pnida);
  11007. if(pnida)
  11008. {
  11009. ZeroMemory(pnida, sizeof(NOTIFYICONDATA));
  11010. pnida->cbSize = sizeof(NOTIFYICONDATA);
  11011. pnida->dwState = lpData->dwState;
  11012. pnida->dwStateMask = lpData->dwStateMask;
  11013. pnida->uTimeout = lpData->uTimeout;
  11014. pnida->dwInfoFlags = lpData->dwInfoFlags;
  11015. WideCharToMultiByte(g_acp, 0, lpData->szInfo, 256, pnida->szInfo, 256, NULL, NULL);
  11016. WideCharToMultiByte(g_acp, 0, lpData->szInfoTitle, 64, pnida->szInfoTitle, 64, NULL, NULL);
  11017. }
  11018. }
  11019. // Members common to both structures
  11020. if(pnida)
  11021. {
  11022. pnida->hWnd = lpData->hWnd;
  11023. pnida->uID = lpData->uID;
  11024. pnida->uFlags = lpData->uFlags;
  11025. pnida->uCallbackMessage = lpData->uCallbackMessage;
  11026. pnida->hIcon = lpData->hIcon;
  11027. WideCharToMultiByte(g_acp, 0, lpData->szTip, 64, pnida->szTip, 64, NULL, NULL);
  11028. // Call the 'A' version of the API
  11029. return(Shell_NotifyIconA(dwMessage, pnida));
  11030. }
  11031. SetLastError(ERROR_STACK_OVERFLOW);
  11032. return(FALSE);
  11033. }
  11034. End=
  11035. [EFunc]
  11036. TemplateName=SHBrowseForFolderW
  11037. Begin=
  11038. LPITEMIDLIST _stdcall
  11039. GodotSHBrowseForFolderW(LPBROWSEINFOW lpbi)
  11040. {
  11041. char buf[_MAX_PATH];
  11042. BROWSEINFOA bi;
  11043. LPITEMIDLIST item;
  11044. bi.hwndOwner = lpbi->hwndOwner;
  11045. bi.pidlRoot = lpbi->pidlRoot;
  11046. bi.pszDisplayName = buf;
  11047. GODOT_TO_ACP_STACKALLOC(lpbi->lpszTitle, bi.lpszTitle);
  11048. bi.ulFlags = lpbi->ulFlags;
  11049. bi.lpfn = lpbi->lpfn;
  11050. bi.lParam = lpbi->lParam;
  11051. bi.iImage = lpbi->iImage;
  11052. if(item = SHBrowseForFolderA(&bi))
  11053. {
  11054. MultiByteToWideChar(g_acp, 0, bi.pszDisplayName, -1, lpbi->pszDisplayName, _MAX_PATH);
  11055. lpbi->iImage = bi.iImage;
  11056. }
  11057. return item;
  11058. }
  11059. End=
  11060. [EFunc]
  11061. TemplateName=SHFileOperationW
  11062. Begin=
  11063. int __stdcall
  11064. GodotSHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp)
  11065. {
  11066. SHFILEOPSTRUCTA sfoa;
  11067. size_t cch;
  11068. ZeroMemory(&sfoa, sizeof(SHFILEOPSTRUCTA));
  11069. sfoa.hwnd = lpFileOp->hwnd;
  11070. sfoa.wFunc = lpFileOp->wFunc;
  11071. sfoa.fFlags = lpFileOp->fFlags;
  11072. sfoa.fAnyOperationsAborted = lpFileOp->fAnyOperationsAborted;
  11073. sfoa.hNameMappings = lpFileOp->hNameMappings;
  11074. cch = cchUnicodeMultiSz(lpFileOp->pFrom);
  11075. if(cch)
  11076. {
  11077. _STACKALLOC((cch*g_mcs + 1), sfoa.pFrom);
  11078. if(!sfoa.pFrom)
  11079. {
  11080. SetLastError(ERROR_STACK_OVERFLOW);
  11081. return(1);
  11082. }
  11083. ZeroMemory((LPSTR)sfoa.pFrom, (cch*g_mcs + 1));
  11084. WideCharToMultiByte(g_acp, 0, lpFileOp->pFrom, cch, (LPSTR)sfoa.pFrom, cch*g_mcs, NULL, NULL);
  11085. }
  11086. cch = cchUnicodeMultiSz(lpFileOp->pTo);
  11087. if(cch)
  11088. {
  11089. _STACKALLOC((cch*g_mcs + 1), sfoa.pTo);
  11090. if(!sfoa.pTo)
  11091. {
  11092. SetLastError(ERROR_STACK_OVERFLOW);
  11093. return(1);
  11094. }
  11095. ZeroMemory((LPSTR)sfoa.pTo, (cch*g_mcs + 1));
  11096. WideCharToMultiByte(g_acp, 0, lpFileOp->pTo, cch, (LPSTR)sfoa.pTo, cch*g_mcs, NULL, NULL);
  11097. }
  11098. GODOT_TO_ACP_STACKALLOC(lpFileOp->lpszProgressTitle, sfoa.lpszProgressTitle);
  11099. return(SHFileOperationA(&sfoa));
  11100. }
  11101. End=
  11102. [EFunc]
  11103. TemplateName=SHGetFileInfoW
  11104. Begin=
  11105. DWORD_PTR __stdcall
  11106. GodotSHGetFileInfoW(LPCWSTR pszPath, DWORD dwFileAttribs, SHFILEINFOW * psfi, UINT cbFileInfo, UINT uFlags)
  11107. {
  11108. // Begin locals
  11109. DWORD_PTR RetVal;
  11110. CHAR pszPathAnsi[_MAX_PATH];
  11111. SHFILEINFOA sfia;
  11112. ZeroMemory(&sfia, sizeof(SHFILEINFOA));
  11113. // If SHGFI_ATTR_SPECIFIED is among uFlags, dwAttributes is taken from the structure
  11114. // We simply initialize it in every case (assuming a pointer was supplied)
  11115. if (psfi)
  11116. sfia.dwAttributes = psfi->dwAttributes;
  11117. // If SHGFI_PIDL is specified, pszPath is actually a pointer to an ITEMIDLIST.
  11118. // Otherwise, convert the string from wide to MBCS
  11119. if (!(uFlags & SHGFI_PIDL))
  11120. {
  11121. WideCharToMultiByte(g_acp, 0, pszPath, _MAX_PATH, pszPathAnsi, _MAX_PATH, NULL, NULL);
  11122. RetVal=SHGetFileInfoA(pszPathAnsi, dwFileAttribs, &sfia, sizeof(SHFILEINFOA), uFlags);
  11123. }
  11124. else
  11125. RetVal=SHGetFileInfoA((LPSTR)pszPath, dwFileAttribs, &sfia, sizeof(SHFILEINFOA), uFlags);
  11126. if (RetVal && psfi)
  11127. {
  11128. psfi->hIcon = sfia.hIcon;
  11129. psfi->iIcon = sfia.iIcon;
  11130. psfi->dwAttributes = sfia.dwAttributes;
  11131. if ((uFlags & (SHGFI_DISPLAYNAME | SHGFI_ICONLOCATION)) && sfia.szDisplayName)
  11132. MultiByteToWideChar(g_acp, 0, sfia.szDisplayName, -1, psfi->szDisplayName, _MAX_PATH);
  11133. else
  11134. psfi->szDisplayName[0] = '\0';
  11135. if ((uFlags & SHGFI_TYPENAME) && sfia.szTypeName)
  11136. MultiByteToWideChar(g_acp, 0, sfia.szTypeName, -1, psfi->szTypeName, 80);
  11137. else
  11138. psfi->szTypeName[0] = '\0';
  11139. }
  11140. // Finished
  11141. return RetVal;
  11142. }
  11143. End=
  11144. [EFunc]
  11145. TemplateName=SHGetNewLinkInfoW
  11146. Begin=
  11147. BOOL __stdcall
  11148. GodotSHGetNewLinkInfoW(LPCWSTR pszLinkTo, LPCWSTR pszDir, LPWSTR pszName, BOOL * pfMustCopy, UINT uFlags)
  11149. {
  11150. BOOL RetVal;
  11151. LPSTR pszDirAnsi;
  11152. char * pszNameAnsi[_MAX_PATH];
  11153. GODOT_TO_ACP_STACKALLOC(pszDir, pszDirAnsi);
  11154. if(uFlags & SHGNLI_PIDL)
  11155. RetVal=SHGetNewLinkInfoA((LPCSTR)pszLinkTo, pszDirAnsi, (LPSTR)pszNameAnsi, pfMustCopy, uFlags);
  11156. else
  11157. {
  11158. LPSTR pszLinkToAnsi;
  11159. GODOT_TO_ACP_STACKALLOC(pszLinkTo, pszLinkToAnsi);
  11160. RetVal=SHGetNewLinkInfoA(pszLinkToAnsi, pszDirAnsi, (LPSTR)pszNameAnsi, pfMustCopy, uFlags);
  11161. }
  11162. if(RetVal)
  11163. MultiByteToWideChar(g_acp, 0, (LPSTR)pszNameAnsi, -1, pszName, _MAX_PATH);
  11164. return RetVal;
  11165. }
  11166. End=
  11167. [EFunc]
  11168. TemplateName=SHGetPathFromIDListW
  11169. Begin=
  11170. BOOL __stdcall
  11171. GodotSHGetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath)
  11172. {
  11173. char buf[_MAX_PATH];
  11174. BOOL fRet;
  11175. if(fRet = SHGetPathFromIDListA(pidl, buf))
  11176. {
  11177. MultiByteToWideChar(g_acp, 0, buf, -1, pszPath, _MAX_PATH);
  11178. }
  11179. return fRet;
  11180. }
  11181. End=
  11182. [EFunc]
  11183. TemplateName=sndPlaySoundW
  11184. Begin=
  11185. BOOL __stdcall
  11186. GodotsndPlaySoundW(LPCWSTR pszSound, UINT fuSound)
  11187. {
  11188. BOOL RetVal;
  11189. LPSTR pszSoundAnsi;
  11190. GODOT_TO_ACP_STACKALLOC(pszSound, pszSoundAnsi);
  11191. RetVal=sndPlaySoundA(pszSoundAnsi, fuSound);
  11192. return RetVal;
  11193. }
  11194. End=
  11195. [EFunc]
  11196. TemplateName=StartDocW
  11197. Begin=
  11198. int __stdcall
  11199. GodotStartDocW(HDC hdc, const DOCINFOW * lpdi)
  11200. {
  11201. if(lpdi==NULL)
  11202. {
  11203. SetLastError(ERROR_INVALID_PARAMETER);
  11204. return(0);
  11205. }
  11206. else
  11207. {
  11208. DOCINFOA dia;
  11209. int RetVal;
  11210. UINT cpg = CpgFromHdc(hdc);
  11211. UINT mcs = CbPerChOfCpg(cpg);
  11212. // Begin precall
  11213. ZeroMemory(&dia, sizeof(DOCINFOA));
  11214. dia.cbSize = sizeof(DOCINFOA);
  11215. GODOT_TO_CPG_STACKALLOC(lpdi->lpszDocName, dia.lpszDocName, cpg, mcs);
  11216. GODOT_TO_CPG_STACKALLOC(lpdi->lpszOutput, dia.lpszOutput, cpg, mcs);
  11217. GODOT_TO_CPG_STACKALLOC(lpdi->lpszDatatype, dia.lpszDatatype, cpg, mcs);
  11218. dia.fwType = lpdi->fwType;
  11219. RetVal = StartDocA(hdc, &dia);
  11220. return(RetVal);
  11221. }
  11222. }
  11223. End=
  11224. [EFunc]
  11225. TemplateName=StartDocPrinterW
  11226. Begin=
  11227. DWORD __stdcall
  11228. GodotStartDocPrinterW(HANDLE hPrinter, DWORD Level, LPBYTE pDocInfo)
  11229. {
  11230. DOC_INFO_2A dcia;
  11231. switch(Level)
  11232. {
  11233. case 2:
  11234. dcia.dwMode = ((LPDOC_INFO_2W)pDocInfo)->dwMode;
  11235. dcia.JobId = ((LPDOC_INFO_2W)pDocInfo)->JobId;
  11236. // fall through to pick up the strings that are shared
  11237. case 1:
  11238. GODOT_TO_ACP_STACKALLOC(((LPDOC_INFO_1W)pDocInfo)->pDocName, dcia.pDocName);
  11239. GODOT_TO_ACP_STACKALLOC(((LPDOC_INFO_1W)pDocInfo)->pOutputFile, dcia.pOutputFile);
  11240. GODOT_TO_ACP_STACKALLOC(((LPDOC_INFO_1W)pDocInfo)->pDatatype, dcia.pDatatype);
  11241. break;
  11242. default:
  11243. SetLastError(ERROR_INVALID_PARAMETER);
  11244. return(0);
  11245. break;
  11246. }
  11247. return(StartDocPrinterA(hPrinter, Level, (LPBYTE)&dcia));
  11248. }
  11249. End=
  11250. [EFunc]
  11251. TemplateName=TextOutW
  11252. Begin=
  11253. BOOL __stdcall
  11254. GodotTextOutW(HDC hdc, int nXStart, int nYStart, LPCWSTR lpString, int cbString)
  11255. {
  11256. // Office does this too: why call TextOutW and have
  11257. // to work around the Win9x bug twice, after all?
  11258. return GodotExtTextOutW(hdc, nXStart, nYStart, 0, NULL, lpString, cbString, NULL);
  11259. }
  11260. End=
  11261. [EFunc]
  11262. TemplateName=SystemParametersInfoW
  11263. Begin=
  11264. BOOL __stdcall GodotSystemParametersInfoW(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni)
  11265. {
  11266. BOOL RetVal = FALSE; // guilty until proven innocent
  11267. // About 1/3 of this code is stolen from VSANSI, but they skip too
  11268. // many uiParams to suit our full needs.
  11269. // APP COMPAT: It seems that Win9x does not require that uiParam set the size if
  11270. // cbSize does, so we need to let them live with this. If either value is set properly,
  11271. // then let them on through.
  11272. switch(uiAction)
  11273. {
  11274. case SPI_GETNONCLIENTMETRICS:
  11275. case SPI_SETNONCLIENTMETRICS:
  11276. {
  11277. PNONCLIENTMETRICSW pncmw = (PNONCLIENTMETRICSW)pvParam;
  11278. if(pncmw &&
  11279. ((pncmw->cbSize == sizeof(NONCLIENTMETRICSW)) ||
  11280. (uiParam == sizeof(NONCLIENTMETRICSW))))
  11281. {
  11282. NONCLIENTMETRICSA ncma;
  11283. ncma.cbSize = sizeof(NONCLIENTMETRICSA);
  11284. if(uiAction == SPI_SETNONCLIENTMETRICS)
  11285. {
  11286. ncma.iBorderWidth = pncmw->iBorderWidth;
  11287. ncma.iScrollWidth = pncmw->iScrollWidth;
  11288. ncma.iScrollHeight = pncmw->iScrollHeight;
  11289. ncma.iCaptionWidth = pncmw->iCaptionWidth;
  11290. ncma.iCaptionHeight = pncmw->iCaptionHeight;
  11291. LogFontAfromW(&ncma.lfCaptionFont, &pncmw->lfCaptionFont);
  11292. ncma.iSmCaptionWidth = pncmw->iSmCaptionWidth;
  11293. ncma.iSmCaptionHeight = pncmw->iSmCaptionHeight;
  11294. LogFontAfromW(&ncma.lfSmCaptionFont, &pncmw->lfSmCaptionFont);
  11295. ncma.iMenuWidth = pncmw->iMenuWidth;
  11296. ncma.iMenuHeight = pncmw->iMenuHeight;
  11297. LogFontAfromW(&ncma.lfMenuFont, &pncmw->lfMenuFont);
  11298. LogFontAfromW(&ncma.lfStatusFont, &pncmw->lfStatusFont);
  11299. LogFontAfromW(&ncma.lfMessageFont, &pncmw->lfMessageFont);
  11300. }
  11301. RetVal = SystemParametersInfoA(uiAction, sizeof(NONCLIENTMETRICSA), &ncma, fWinIni);
  11302. if(RetVal &&
  11303. (uiAction == SPI_GETNONCLIENTMETRICS))
  11304. {
  11305. pncmw->cbSize = sizeof(NONCLIENTMETRICSW);
  11306. pncmw->iBorderWidth = ncma.iBorderWidth;
  11307. pncmw->iScrollWidth = ncma.iScrollWidth;
  11308. pncmw->iScrollHeight = ncma.iScrollHeight;
  11309. pncmw->iCaptionWidth = ncma.iCaptionWidth;
  11310. pncmw->iCaptionHeight = ncma.iCaptionHeight;
  11311. LogFontWfromA(&pncmw->lfCaptionFont, &ncma.lfCaptionFont);
  11312. pncmw->iSmCaptionWidth = ncma.iSmCaptionWidth;
  11313. pncmw->iSmCaptionHeight = ncma.iSmCaptionHeight;
  11314. LogFontWfromA(&pncmw->lfSmCaptionFont, &ncma.lfSmCaptionFont);
  11315. pncmw->iMenuWidth = ncma.iMenuWidth;
  11316. pncmw->iMenuHeight = ncma.iMenuHeight;
  11317. LogFontWfromA(&pncmw->lfMenuFont, &ncma.lfMenuFont);
  11318. LogFontWfromA(&pncmw->lfStatusFont, &ncma.lfStatusFont);
  11319. LogFontWfromA(&pncmw->lfMessageFont, &ncma.lfMessageFont);
  11320. }
  11321. }
  11322. else
  11323. SetLastError(ERROR_INVALID_PARAMETER);
  11324. break;
  11325. }
  11326. case SPI_GETHIGHCONTRAST:
  11327. case SPI_SETHIGHCONTRAST:
  11328. {
  11329. LPHIGHCONTRASTW phc = (LPHIGHCONTRASTW)pvParam;
  11330. if(phc &&
  11331. ((phc->cbSize == sizeof(HIGHCONTRASTW)) ||
  11332. (uiParam == sizeof(HIGHCONTRASTW))))
  11333. {
  11334. HIGHCONTRASTA hca;
  11335. ZeroMemory(&hca, sizeof(HIGHCONTRASTA));
  11336. hca.cbSize = sizeof(HIGHCONTRASTA);
  11337. if(uiAction == SPI_SETHIGHCONTRAST)
  11338. {
  11339. hca.dwFlags = phc->dwFlags;
  11340. GODOT_TO_ACP_STACKALLOC(phc->lpszDefaultScheme, hca.lpszDefaultScheme);
  11341. }
  11342. else
  11343. {
  11344. _STACKALLOC(LF_FULLFACESIZE, hca.lpszDefaultScheme);
  11345. }
  11346. if((hca.lpszDefaultScheme == NULL) &&
  11347. (phc->lpszDefaultScheme != NULL))
  11348. {
  11349. return(FALSE);
  11350. }
  11351. RetVal = SystemParametersInfoA(uiAction, sizeof(HIGHCONTRASTA), &hca, fWinIni);
  11352. if(RetVal &&
  11353. (uiAction == SPI_GETHIGHCONTRAST))
  11354. {
  11355. phc->cbSize = sizeof(HIGHCONTRASTW);
  11356. phc->dwFlags = hca.dwFlags;
  11357. if(FSTRING_VALID(hca.lpszDefaultScheme) &&
  11358. FSTRING_VALID(phc->lpszDefaultScheme))
  11359. {
  11360. MultiByteToWideChar(g_acp, 0, hca.lpszDefaultScheme, -1,
  11361. phc->lpszDefaultScheme, LF_FULLFACESIZE);
  11362. }
  11363. }
  11364. }
  11365. else
  11366. SetLastError(ERROR_INVALID_PARAMETER);
  11367. break;
  11368. }
  11369. case SPI_GETICONMETRICS:
  11370. case SPI_SETICONMETRICS:
  11371. {
  11372. LPICONMETRICSW lpimw = (LPICONMETRICSW)pvParam;
  11373. if(lpimw &&
  11374. ((lpimw->cbSize == sizeof(ICONMETRICSW)) ||
  11375. (uiParam == sizeof(ICONMETRICSW))))
  11376. {
  11377. ICONMETRICSA ima;
  11378. LPLOGFONTW lplfw = &lpimw->lfFont;
  11379. LPLOGFONTA lplfa = &ima.lfFont;
  11380. ZeroMemory(&ima, sizeof(ICONMETRICSA));
  11381. ima.cbSize = sizeof(ICONMETRICSA);
  11382. if(uiAction == SPI_SETICONMETRICS)
  11383. {
  11384. ima.iHorzSpacing = lpimw->iHorzSpacing;
  11385. ima.iVertSpacing = lpimw->iVertSpacing;
  11386. ima.iTitleWrap = lpimw->iTitleWrap;
  11387. LogFontAfromW(lplfa, lplfw);
  11388. }
  11389. RetVal = SystemParametersInfoA(uiAction, sizeof(ICONMETRICSA), &ima, fWinIni);
  11390. if(RetVal &&
  11391. (uiAction == SPI_GETICONMETRICS))
  11392. {
  11393. lpimw->cbSize = sizeof(ICONMETRICSW);
  11394. lpimw->iHorzSpacing = ima.iHorzSpacing;
  11395. lpimw->iVertSpacing = ima.iVertSpacing;
  11396. lpimw->iTitleWrap = ima.iTitleWrap;
  11397. LogFontWfromA(lplfw, lplfa);
  11398. }
  11399. }
  11400. else
  11401. SetLastError(ERROR_INVALID_PARAMETER);
  11402. break;
  11403. }
  11404. case SPI_GETICONTITLELOGFONT:
  11405. case SPI_SETICONTITLELOGFONT:
  11406. {
  11407. if (uiParam == sizeof(LOGFONTW))
  11408. {
  11409. LOGFONTA lfa;
  11410. LPLOGFONTW lplfw = (LPLOGFONTW)pvParam;
  11411. ZeroMemory(&lfa, sizeof(LOGFONTA));
  11412. if(uiAction == SPI_SETICONTITLELOGFONT)
  11413. LogFontAfromW(&lfa, lplfw);
  11414. RetVal = SystemParametersInfoA(uiAction, sizeof(LOGFONTA), &lfa, fWinIni);
  11415. if(RetVal && (uiAction == SPI_GETICONTITLELOGFONT))
  11416. LogFontWfromA(lplfw, &lfa);
  11417. }
  11418. else
  11419. SetLastError(ERROR_INVALID_PARAMETER);
  11420. break;
  11421. }
  11422. case SPI_GETSERIALKEYS:
  11423. case SPI_SETSERIALKEYS:
  11424. {
  11425. LPSERIALKEYSW lpskw = (LPSERIALKEYSW)pvParam;
  11426. if(lpskw &&
  11427. ((lpskw->cbSize == sizeof(SERIALKEYSW)) ||
  11428. (uiParam == sizeof(SERIALKEYSW))))
  11429. {
  11430. SERIALKEYSA ska;
  11431. ZeroMemory(&ska, sizeof(SERIALKEYSA));
  11432. GODOT_TO_ACP_STACKALLOC(lpskw->lpszActivePort, ska.lpszActivePort);
  11433. if((ska.lpszActivePort == NULL) &&
  11434. (lpskw->lpszActivePort != NULL))
  11435. {
  11436. return(FALSE);
  11437. }
  11438. ska.lpszPort = NULL;
  11439. ska.cbSize = sizeof(SERIALKEYSA);
  11440. if(uiAction == SPI_SETSERIALKEYS)
  11441. {
  11442. ska.dwFlags = lpskw->dwFlags;
  11443. ska.iBaudRate = lpskw->iBaudRate;
  11444. ska.iPortState = lpskw->iPortState;
  11445. ska.iActive = lpskw->iActive;
  11446. }
  11447. RetVal = SystemParametersInfoA(uiAction, sizeof(SERIALKEYSA), &ska, fWinIni);
  11448. if(RetVal &&
  11449. (uiAction == SPI_GETSERIALKEYS))
  11450. {
  11451. lpskw->cbSize = sizeof(SERIALKEYSW);
  11452. lpskw->dwFlags = ska.dwFlags;
  11453. lpskw->iBaudRate = ska.iBaudRate;
  11454. lpskw->iPortState = ska.iPortState;
  11455. lpskw->iActive = ska.iActive;
  11456. }
  11457. }
  11458. else
  11459. SetLastError(ERROR_INVALID_PARAMETER);
  11460. break;
  11461. }
  11462. case SPI_GETSOUNDSENTRY:
  11463. case SPI_SETSOUNDSENTRY:
  11464. {
  11465. LPSOUNDSENTRYW lpssw = (LPSOUNDSENTRYW)pvParam;
  11466. if(lpssw &&
  11467. ((lpssw->cbSize == sizeof(SOUNDSENTRYW)) ||
  11468. (uiParam == sizeof(SOUNDSENTRYW))))
  11469. {
  11470. SOUNDSENTRYA ssa;
  11471. ZeroMemory(&ssa, sizeof(SOUNDSENTRYA));
  11472. ssa.cbSize = sizeof(SOUNDSENTRYA);
  11473. if(uiAction == SPI_GETSOUNDSENTRY)
  11474. {
  11475. _STACKALLOC(MAX_PATH, ssa.lpszWindowsEffectDLL);
  11476. }
  11477. else // if(uiAction==SPI_SETSOUNDSENTRY)
  11478. {
  11479. ssa.dwFlags = lpssw->dwFlags;
  11480. ssa.iFSTextEffect = lpssw->iFSTextEffect;
  11481. ssa.iFSTextEffectMSec = lpssw->iFSTextEffectMSec;
  11482. ssa.iFSTextEffectColorBits = lpssw->iFSTextEffectColorBits;
  11483. ssa.iFSGrafEffect = lpssw->iFSGrafEffect;
  11484. ssa.iFSGrafEffectMSec = lpssw->iFSGrafEffectMSec;
  11485. ssa.iFSGrafEffectColor = lpssw->iFSGrafEffectColor;
  11486. ssa.iWindowsEffect = lpssw->iWindowsEffect;
  11487. ssa.iWindowsEffectMSec = lpssw->iWindowsEffectMSec;
  11488. GODOT_TO_ACP_STACKALLOC(lpssw->lpszWindowsEffectDLL, ssa.lpszWindowsEffectDLL);
  11489. ssa.iWindowsEffectOrdinal = lpssw->iWindowsEffectOrdinal;
  11490. }
  11491. if((ssa.lpszWindowsEffectDLL == NULL) &&
  11492. (lpssw->lpszWindowsEffectDLL != NULL))
  11493. {
  11494. return(FALSE);
  11495. }
  11496. RetVal = SystemParametersInfoA(uiAction, sizeof(SOUNDSENTRYA), &ssa, fWinIni);
  11497. if(RetVal &&
  11498. (uiAction == SPI_GETSOUNDSENTRY))
  11499. {
  11500. lpssw->cbSize = sizeof(SOUNDSENTRYW);
  11501. lpssw->dwFlags = ssa.dwFlags;
  11502. lpssw->iFSTextEffect = ssa.iFSTextEffect;
  11503. lpssw->iFSTextEffectMSec = ssa.iFSTextEffectMSec;
  11504. lpssw->iFSTextEffectColorBits = ssa.iFSTextEffectColorBits;
  11505. lpssw->iFSGrafEffect = ssa.iFSGrafEffect;
  11506. lpssw->iFSGrafEffectMSec = ssa.iFSGrafEffectMSec;
  11507. lpssw->iFSGrafEffectColor = ssa.iFSGrafEffectColor;
  11508. lpssw->iWindowsEffect = ssa.iWindowsEffect;
  11509. lpssw->iWindowsEffectMSec = ssa.iWindowsEffectMSec;
  11510. MultiByteToWideChar(g_acp, 0,
  11511. ssa.lpszWindowsEffectDLL, -1,
  11512. lpssw->lpszWindowsEffectDLL, MAX_PATH);
  11513. lpssw->iWindowsEffectOrdinal = ssa.iWindowsEffectOrdinal;
  11514. }
  11515. }
  11516. else
  11517. SetLastError(ERROR_INVALID_PARAMETER);
  11518. break;
  11519. }
  11520. case SPI_SETDESKWALLPAPER:
  11521. case SPI_GETDESKWALLPAPER:
  11522. {
  11523. LPSTR pvParamAnsi = NULL;
  11524. if(uiAction == SPI_SETDESKWALLPAPER)
  11525. GODOT_TO_ACP_STACKALLOC(pvParam, pvParamAnsi);
  11526. else
  11527. _STACKALLOC(MAX_PATH + 1, pvParamAnsi);
  11528. if((pvParamAnsi == NULL) &&
  11529. (pvParam != NULL))
  11530. {
  11531. return(FALSE);
  11532. }
  11533. RetVal = SystemParametersInfoA(uiAction, uiParam, pvParamAnsi, fWinIni);
  11534. if(RetVal &&
  11535. (uiAction == SPI_GETDESKWALLPAPER) &&
  11536. FSTRING_VALID(pvParamAnsi) &&
  11537. FSTRING_VALID((LPWSTR)pvParam))
  11538. {
  11539. MultiByteToWideChar(g_acp, 0, pvParamAnsi, -1, (LPWSTR)pvParam, MAX_PATH);
  11540. }
  11541. break;
  11542. }
  11543. default:
  11544. {
  11545. // Call the 'A' version of the API without conversion, etc.
  11546. RetVal = SystemParametersInfoA(uiAction, uiParam, pvParam, fWinIni);
  11547. break;
  11548. }
  11549. }
  11550. // Finished
  11551. return RetVal;
  11552. }
  11553. End=
  11554. [EFunc]
  11555. TemplateName=TranslateAcceleratorW
  11556. Begin=
  11557. int __stdcall
  11558. GodotTranslateAcceleratorW(HWND hWnd, HACCEL hAccTable, LPMSG lpMsg)
  11559. {
  11560. return((int)GodotDispatchMessage(mtTranslateAccelerator, hWnd, hAccTable, lpMsg));
  11561. }
  11562. End=
  11563. [EFunc]
  11564. TemplateName=UpdateResourceW
  11565. Begin=
  11566. BOOL __stdcall GodotUpdateResourceW(HANDLE hUpdate, LPCWSTR lpType, LPCWSTR lpName,
  11567. WORD wLanguage, LPVOID lpData, DWORD cbData)
  11568. {
  11569. // UNSUPPORTED FUNCTION: Documented as a failure stub
  11570. return(UpdateResourceInternalW(hUpdate, lpType, lpName, wLanguage, lpData, cbData));
  11571. }
  11572. End=
  11573. [EFunc]
  11574. TemplateName=VerFindFileW
  11575. Begin=
  11576. DWORD __stdcall
  11577. GodotVerFindFileW( DWORD uFlags,
  11578. LPWSTR szFileName,
  11579. LPWSTR szWinDir,
  11580. LPWSTR szAppDir,
  11581. LPWSTR szCurDir,
  11582. PUINT lpuCurDirLen,
  11583. LPWSTR szDestDir,
  11584. PUINT lpuDestDirLen
  11585. )
  11586. {
  11587. // Begin locals
  11588. DWORD RetVal;
  11589. LPSTR szFileNameAnsi, szWinDirAnsi, szAppDirAnsi;
  11590. char szCurDirAnsi[MAX_PATH + 1];
  11591. char szDestDirAnsi[MAX_PATH + 1];
  11592. UINT uCurDirLen, uDestDirLen;
  11593. // Begin precall
  11594. GODOT_TO_ACP_STACKALLOC(szFileName, szFileNameAnsi);
  11595. GODOT_TO_ACP_STACKALLOC(szWinDir, szWinDirAnsi);
  11596. GODOT_TO_ACP_STACKALLOC(szAppDir, szAppDirAnsi);
  11597. if((!szFileNameAnsi && szFileName) ||
  11598. (!szWinDirAnsi && szWinDir) ||
  11599. (!szAppDirAnsi && szAppDir))
  11600. return(0);
  11601. uCurDirLen = *lpuCurDirLen * g_mcs;
  11602. uDestDirLen= *lpuDestDirLen * g_mcs;
  11603. ZeroMemory(szCurDirAnsi, MAX_PATH + 1);
  11604. ZeroMemory(szDestDirAnsi, MAX_PATH + 1);
  11605. RetVal=VerFindFileA(uFlags, szFileNameAnsi, szWinDirAnsi, szAppDirAnsi, szCurDirAnsi,
  11606. &uCurDirLen, szDestDirAnsi, &uDestDirLen);
  11607. // Begin postcall: note that we do not care what the return value
  11608. // really was,since these buffer sizes are set either way.
  11609. if(uCurDirLen > *lpuCurDirLen)
  11610. *lpuCurDirLen = uCurDirLen;
  11611. else
  11612. {
  11613. MultiByteToWideChar(g_acp, 0, szCurDirAnsi, -1, szCurDir, *lpuCurDirLen);
  11614. *lpuCurDirLen = gwcslen(szCurDir);
  11615. }
  11616. if(uDestDirLen > *lpuDestDirLen)
  11617. *lpuDestDirLen = uCurDirLen;
  11618. else
  11619. {
  11620. // Convert the full length of the ANSI name into the full size of the Unicode buffer
  11621. MultiByteToWideChar(g_acp, 0, szDestDirAnsi, -1, szDestDir, *lpuDestDirLen);
  11622. *lpuDestDirLen = gwcslen(szDestDir);
  11623. }
  11624. // Finished
  11625. return RetVal;
  11626. }
  11627. End=
  11628. [EFunc]
  11629. TemplateName=VerInstallFileW
  11630. Begin=
  11631. DWORD __stdcall
  11632. GodotVerInstallFileW( DWORD uFlags,
  11633. LPWSTR szSrcFileName,
  11634. LPWSTR szDestFileName,
  11635. LPWSTR szSrcDir,
  11636. LPWSTR szDestDir,
  11637. LPWSTR szCurDir,
  11638. LPWSTR szTmpFile,
  11639. PUINT lpuTmpFileLen
  11640. )
  11641. {
  11642. // Begin locals
  11643. DWORD RetVal;
  11644. LPSTR szSrcFileNameAnsi, szDestFileNameAnsi, szSrcDirAnsi, szDestDirAnsi, szCurDirAnsi;
  11645. CHAR szTmpFileAnsi[MAX_PATH + 1];
  11646. UINT uTmpFileLen;
  11647. // Begin precall
  11648. GODOT_TO_ACP_STACKALLOC(szSrcFileName, szSrcFileNameAnsi);
  11649. GODOT_TO_ACP_STACKALLOC(szDestFileName, szDestFileNameAnsi);
  11650. GODOT_TO_ACP_STACKALLOC(szSrcDir, szSrcDirAnsi);
  11651. GODOT_TO_ACP_STACKALLOC(szDestDir, szDestDirAnsi);
  11652. GODOT_TO_ACP_STACKALLOC(szCurDir, szCurDirAnsi);
  11653. if((!szSrcFileNameAnsi && szSrcFileName) ||
  11654. (!szDestFileNameAnsi && szDestFileName) ||
  11655. (!szSrcDirAnsi && szSrcDir) ||
  11656. (!szDestDirAnsi && szDestDir) ||
  11657. (!szCurDirAnsi && szCurDir))
  11658. return(0);
  11659. uTmpFileLen = *lpuTmpFileLen * g_mcs;
  11660. ZeroMemory(&szTmpFileAnsi, MAX_PATH + 1);
  11661. RetVal=VerInstallFileA(uFlags, szSrcFileNameAnsi, szDestFileNameAnsi, szSrcDirAnsi,
  11662. szDestDirAnsi, szCurDirAnsi, szTmpFileAnsi, &uTmpFileLen);
  11663. // Begin postcall: note that we do not care what the return value
  11664. // really was,since these buffer sizes must be set either way.
  11665. if(uTmpFileLen > *lpuTmpFileLen)
  11666. *lpuTmpFileLen = uTmpFileLen;
  11667. else
  11668. {
  11669. // Convert the full length of the ANSI name into the full size of the Unicode buffer
  11670. MultiByteToWideChar(g_acp, 0, szTmpFileAnsi, -1, szTmpFile, *lpuTmpFileLen);
  11671. *lpuTmpFileLen = gwcslen(szTmpFile);
  11672. }
  11673. // Finished
  11674. return RetVal;
  11675. }
  11676. End=
  11677. [EFunc]
  11678. TemplateName=VerLanguageNameW
  11679. Begin=
  11680. DWORD __stdcall
  11681. GodotVerLanguageNameW(DWORD wLang, LPWSTR szLang, DWORD nSize)
  11682. {
  11683. DWORD RetVal;
  11684. LPSTR szLangAnsi = NULL;
  11685. _STACKALLOC((nSize *g_mcs) + 1, szLangAnsi);
  11686. if(szLangAnsi==NULL)
  11687. {
  11688. return(0);
  11689. }
  11690. ZeroMemory(szLangAnsi, (nSize * g_mcs) + 1);
  11691. RetVal=VerLanguageNameA(wLang, szLangAnsi, nSize);
  11692. // kinda sucks but we are not being any worse than
  11693. // the OS is here -- See Windows Bugs # 311758 for
  11694. // more details
  11695. if(szLang)
  11696. {
  11697. if (RetVal < nSize)
  11698. MultiByteToWideChar(g_acp, 0, szLangAnsi, -1, szLang, RetVal);
  11699. else
  11700. MultiByteToWideChar(g_acp, 0, szLangAnsi, -1, szLang, nSize);
  11701. }
  11702. // Finished
  11703. return RetVal;
  11704. }
  11705. End=
  11706. [EFunc]
  11707. TemplateName=VerQueryValueW
  11708. Begin=
  11709. BOOL __stdcall
  11710. GodotVerQueryValueW(const LPVOID pBlock, LPWSTR lpSubBlock, LPVOID * lplpBuffer, PUINT puLen)
  11711. {
  11712. const WCHAR pwzStringFileInfo[] = L"\\StringFileInfo";
  11713. BOOL RetVal;
  11714. LPSTR lpSubBlockAnsi;
  11715. BYTE* pbyt;
  11716. LPWSTR lpwz;
  11717. // Begin precall
  11718. GODOT_TO_ACP_STACKALLOC(lpSubBlock, lpSubBlockAnsi);
  11719. if(lpSubBlockAnsi==NULL)
  11720. {
  11721. return(FALSE);
  11722. }
  11723. pbyt = (BYTE*)pBlock + VERINFO_BUFFER;
  11724. RetVal=VerQueryValueA((void *)pbyt, lpSubBlockAnsi, lplpBuffer, puLen);
  11725. if (RetVal && (gwcsncmp(pwzStringFileInfo, lpSubBlock, gwcslen(pwzStringFileInfo)) == 0))
  11726. {
  11727. // Ok, this means we have to convert. We have a string. :-)
  11728. lpwz = (LPWSTR)pBlock;
  11729. if (*puLen == 0)
  11730. lpwz = L'\0';
  11731. else
  11732. MultiByteToWideChar(g_acp, 0, *lplpBuffer, -1, lpwz, VERINFO_BUFFER/sizeof(WCHAR));
  11733. if(lplpBuffer)
  11734. *lplpBuffer = lpwz;
  11735. }
  11736. // Finished
  11737. return RetVal;
  11738. }
  11739. End=
  11740. [EFunc]
  11741. TemplateName=VkKeyScanW
  11742. Begin=
  11743. SHORT __stdcall
  11744. GodotVkKeyScanW(WCHAR ch)
  11745. {
  11746. char chAnsi;
  11747. UINT cpg = CpgFromLocale(LOWORD(GetKeyboardLayout(0)));
  11748. UINT mcs = CbPerChOfCpg(cpg);
  11749. WideCharToMultiByte(cpg, 0, (WCHAR *)&ch, 1, (CHAR *)&chAnsi, sizeof(char), NULL, NULL);
  11750. return(VkKeyScanA(chAnsi));
  11751. }
  11752. End=
  11753. [EFunc]
  11754. TemplateName=VkKeyScanExW
  11755. Begin=
  11756. SHORT __stdcall
  11757. GodotVkKeyScanExW(WCHAR ch, HKL dwhkl)
  11758. {
  11759. char chAnsi;
  11760. UINT cpg = CpgFromLocale(LOWORD(dwhkl));
  11761. UINT mcs = CbPerChOfCpg(cpg);
  11762. WideCharToMultiByte(cpg, 0, (WCHAR *)&ch, 1, (CHAR *)&chAnsi, sizeof(char), NULL, NULL);
  11763. return(VkKeyScanExA(chAnsi, dwhkl));
  11764. }
  11765. End=
  11766. [EFunc]
  11767. TemplateName=waveInGetDevCapsW
  11768. Begin=
  11769. MMRESULT __stdcall GodotwaveInGetDevCapsW(UINT_PTR uDeviceID, LPWAVEINCAPSW pwic, UINT cbwic)
  11770. {
  11771. // UNSUPPORTED FUNCTION: Documented as a failure stub
  11772. if(cbwic < sizeof(WAVEINCAPSW))
  11773. {
  11774. return(MMSYSERR_INVALPARAM);
  11775. }
  11776. else
  11777. {
  11778. WAVEINCAPSA wicA;
  11779. MMRESULT RetVal;
  11780. ZeroMemory(&wicA, sizeof(WAVEINCAPSA));
  11781. RetVal = waveInGetDevCapsA(uDeviceID, &wicA, sizeof(WAVEINCAPSA));
  11782. if(RetVal == MMSYSERR_NOERROR)
  11783. {
  11784. pwic->wMid = wicA.wMid;
  11785. pwic->wPid = wicA.wPid;
  11786. pwic->vDriverVersion = wicA.vDriverVersion;
  11787. pwic->dwFormats = wicA.dwFormats;
  11788. pwic->wChannels = wicA.wChannels;
  11789. pwic->wReserved1 = wicA.wReserved1;
  11790. MultiByteToWideChar(g_acp, 0, wicA.szPname, MAXPNAMELEN, pwic->szPname, MAXPNAMELEN);
  11791. }
  11792. return(RetVal);
  11793. }
  11794. }
  11795. End=
  11796. [EFunc]
  11797. TemplateName=waveInGetErrorTextW
  11798. Begin=
  11799. MMRESULT __stdcall GodotwaveInGetErrorTextW(MMRESULT mmrError, LPWSTR pszText, UINT cchText)
  11800. {
  11801. // UNSUPPORTED FUNCTION: Documented as a failure stub
  11802. if(pszText==NULL || cchText == 0)
  11803. return(waveInGetErrorTextA(mmrError, (LPSTR)pszText, cchText));
  11804. else
  11805. {
  11806. LPSTR pszTextA;
  11807. MMRESULT RetVal;
  11808. _STACKALLOC((cchText * g_mcs) + 1, pszTextA);
  11809. if(!pszTextA)
  11810. return(MMSYSERR_NOMEM);
  11811. ZeroMemory(pszTextA, (cchText * g_mcs) + 1);
  11812. RetVal = waveInGetErrorTextA(mmrError, pszTextA, cchText);
  11813. if(RetVal == MMSYSERR_NOERROR)
  11814. MultiByteToWideChar(g_acp, 0, pszTextA, -1, pszText, cchText);
  11815. return(RetVal);
  11816. }
  11817. }
  11818. End=
  11819. [EFunc]
  11820. TemplateName=waveOutGetDevCapsW
  11821. Begin=
  11822. MMRESULT __stdcall GodotwaveOutGetDevCapsW(UINT_PTR uDeviceID, LPWAVEOUTCAPSW pwoc, UINT cbwoc)
  11823. {
  11824. // UNSUPPORTED FUNCTION: Documented as a failure stub
  11825. if(cbwoc < sizeof(WAVEOUTCAPSW))
  11826. {
  11827. return(MMSYSERR_INVALPARAM);
  11828. }
  11829. else
  11830. {
  11831. WAVEOUTCAPSA wocA;
  11832. MMRESULT RetVal;
  11833. ZeroMemory(&wocA, sizeof(WAVEOUTCAPS));
  11834. RetVal = waveOutGetDevCapsA(uDeviceID, &wocA, sizeof(WAVEOUTCAPSA));
  11835. if(RetVal == MMSYSERR_NOERROR)
  11836. {
  11837. pwoc->wMid = wocA.wMid;
  11838. pwoc->wPid = wocA.wPid;
  11839. pwoc->vDriverVersion = wocA.vDriverVersion;
  11840. pwoc->dwFormats = wocA.dwFormats;
  11841. pwoc->wChannels = wocA.wChannels;
  11842. pwoc->wReserved1 = wocA.wReserved1;
  11843. pwoc->dwSupport = wocA.dwSupport;
  11844. MultiByteToWideChar(g_acp, 0, wocA.szPname, MAXPNAMELEN, pwoc->szPname, MAXPNAMELEN);
  11845. }
  11846. return(RetVal);
  11847. }
  11848. }
  11849. End=
  11850. [EFunc]
  11851. TemplateName=waveOutGetErrorTextW
  11852. Begin=
  11853. MMRESULT __stdcall GodotwaveOutGetErrorTextW(MMRESULT mmrError, LPWSTR pszText, UINT cchText)
  11854. {
  11855. // UNSUPPORTED FUNCTION: Documented as a failure stub
  11856. if(pszText==NULL || cchText == 0)
  11857. return(waveOutGetErrorTextA(mmrError, (LPSTR)pszText, cchText));
  11858. else
  11859. {
  11860. LPSTR pszTextA;
  11861. MMRESULT RetVal;
  11862. _STACKALLOC((cchText * g_mcs) + 1, pszTextA);
  11863. if(!pszTextA)
  11864. return(MMSYSERR_NOMEM);
  11865. ZeroMemory(pszTextA, (cchText * g_mcs) + 1);
  11866. RetVal = waveOutGetErrorTextA(mmrError, pszTextA, cchText);
  11867. if(RetVal == MMSYSERR_NOERROR)
  11868. MultiByteToWideChar(g_acp, 0, pszTextA, -1, pszText, cchText);
  11869. return(RetVal);
  11870. }
  11871. }
  11872. End=
  11873. [EFunc]
  11874. TemplateName=WideCharToMultiByte
  11875. Begin=
  11876. // WideCharToMultiByte is wrapped for UTF-7/UTF-8 support
  11877. int __stdcall
  11878. GodotWideCharToMultiByte( UINT CodePage,
  11879. DWORD dwFlags,
  11880. LPCWSTR lpWideCharStr,
  11881. int cchWideChar,
  11882. LPSTR lpMultiByteStr,
  11883. int cbMultiByte,
  11884. LPCSTR lpDefaultChar,
  11885. LPBOOL lpUsedDefaultChar
  11886. )
  11887. {
  11888. UINT cpg = ((CodePage == CP_THREAD_ACP) ? g_acp : CodePage);
  11889. // See if it's a special code page value for UTF translations.
  11890. if (cpg >= NLS_CP_ALGORITHM_RANGE)
  11891. return(UnicodeToUTF(cpg, dwFlags, lpWideCharStr, cchWideChar,
  11892. lpMultiByteStr, cbMultiByte, lpDefaultChar, lpUsedDefaultChar));
  11893. // GB 18030 specified?
  11894. if (cpg == CP_GB18030)
  11895. return(GB18030Helper(cpg,
  11896. dwFlags | NLS_CP_WCTOMB,
  11897. lpMultiByteStr,
  11898. cbMultiByte,
  11899. (LPWSTR)lpWideCharStr,
  11900. cchWideChar,
  11901. NULL));
  11902. return(WideCharToMultiByte(cpg, dwFlags, lpWideCharStr, cchWideChar,
  11903. lpMultiByteStr, cbMultiByte, lpDefaultChar, lpUsedDefaultChar));
  11904. }
  11905. End=
  11906. [EFunc]
  11907. TemplateName=WinHelpW
  11908. Begin=
  11909. BOOL __stdcall
  11910. GodotWinHelpW(HWND hWndMain, LPCWSTR lpszHelp, UINT uCommand, ULONG_PTR dwData)
  11911. {
  11912. LPSTR lpszHelpAnsi;
  11913. GODOT_TO_ACP_STACKALLOC(lpszHelp, lpszHelpAnsi);
  11914. switch(uCommand & ~HELP_TCARD)
  11915. {
  11916. case HELP_COMMAND:
  11917. case HELP_KEY:
  11918. case HELP_PARTIALKEY:
  11919. {
  11920. ULONG_PTR dwDataAnsi;
  11921. GODOT_TO_ACP_STACKALLOC(dwData, dwDataAnsi);
  11922. return(WinHelpA(hWndMain, lpszHelpAnsi, uCommand, dwData));
  11923. break;
  11924. }
  11925. case HELP_MULTIKEY:
  11926. {
  11927. LPMULTIKEYHELPW lpmkh = (LPMULTIKEYHELPW)dwData;
  11928. MULTIKEYHELPA mkhA;
  11929. char * szKeyPhrase;
  11930. size_t cchKeyPhrase;
  11931. ZeroMemory(&mkhA, sizeof(MULTIKEYHELPA));
  11932. mkhA.mkSize = sizeof(MULTIKEYHELPA);
  11933. WideCharToMultiByte(g_acp, 0,
  11934. (WCHAR *)&(lpmkh->mkKeylist), 1,
  11935. (CHAR *)&(mkhA.mkKeylist), sizeof(char),
  11936. NULL, NULL);
  11937. cchKeyPhrase = gwcslen(lpmkh->szKeyphrase) + 1;
  11938. _STACKALLOC(cchKeyPhrase*g_mcs, szKeyPhrase);
  11939. WideCharToMultiByte(g_acp, 0,
  11940. lpmkh->szKeyphrase, cchKeyPhrase,
  11941. szKeyPhrase, cchKeyPhrase*g_mcs,
  11942. NULL, NULL);
  11943. lstrcpyA(mkhA.szKeyphrase, szKeyPhrase);
  11944. return(WinHelpA(hWndMain, lpszHelpAnsi, uCommand, (ULONG_PTR)&mkhA));
  11945. break;
  11946. }
  11947. case HELP_SETWINPOS:
  11948. {
  11949. LPHELPWININFOW lphwi = (LPHELPWININFOW)dwData;
  11950. LPHELPWININFOA lphwiA;
  11951. LPSTR lpAnsiKey;
  11952. size_t cchMember;
  11953. BOOL RetVal;
  11954. lphwiA = LocalAlloc(LPTR, (lphwi->wStructSize));
  11955. if(!lphwiA)
  11956. return(FALSE);
  11957. else
  11958. {
  11959. *lphwiA = *((LPHELPWININFOA)dwData); // copies identical parts
  11960. lphwiA->wStructSize = sizeof(HELPWININFOA);
  11961. cchMember = gwcslen(lphwi->rgchMember) + 1;
  11962. _STACKALLOC(cchMember*g_mcs, lpAnsiKey);
  11963. WideCharToMultiByte(g_acp,
  11964. 0,
  11965. lphwi->rgchMember,
  11966. cchMember,
  11967. lpAnsiKey,
  11968. cchMember*g_mcs,
  11969. NULL,
  11970. NULL);
  11971. lstrcpyA(lphwiA->rgchMember, lpAnsiKey);
  11972. RetVal = WinHelpA(hWndMain, lpszHelpAnsi, uCommand, (ULONG_PTR)lphwiA);
  11973. LocalFree(lphwiA);
  11974. return(RetVal);
  11975. }
  11976. break;
  11977. }
  11978. default:
  11979. return(WinHelpA(hWndMain, lpszHelpAnsi, uCommand, dwData));
  11980. break;
  11981. }
  11982. }
  11983. End=
  11984. [EFunc]
  11985. TemplateName=WNetAddConnection2W
  11986. Begin=
  11987. DWORD __stdcall
  11988. GodotWNetAddConnection2W(LPNETRESOURCEW lpnrw, LPCWSTR lpPassword, LPCWSTR lpUserName, DWORD dwFlags)
  11989. {
  11990. // Begin locals
  11991. LPSTR lpPasswordAnsi;
  11992. LPSTR lpUserNameAnsi;
  11993. NETRESOURCEA nra;
  11994. // Begin precall
  11995. ZeroMemory(&nra, sizeof(NETRESOURCEA));
  11996. memcpy(&nra, lpnrw, (4*sizeof(DWORD)));
  11997. GODOT_TO_ACP_STACKALLOC(lpnrw->lpLocalName, nra.lpLocalName);
  11998. GODOT_TO_ACP_STACKALLOC(lpnrw->lpRemoteName, nra.lpRemoteName);
  11999. GODOT_TO_ACP_STACKALLOC(lpnrw->lpComment, nra.lpComment);
  12000. GODOT_TO_ACP_STACKALLOC(lpnrw->lpProvider, nra.lpProvider);
  12001. GODOT_TO_ACP_STACKALLOC(lpUserName, lpUserNameAnsi);
  12002. GODOT_TO_ACP_STACKALLOC(lpPassword, lpPasswordAnsi);
  12003. if((!nra.lpLocalName && lpnrw->lpLocalName) ||
  12004. (!nra.lpLocalName && lpnrw->lpLocalName) ||
  12005. (!nra.lpLocalName && lpnrw->lpLocalName) ||
  12006. (!nra.lpLocalName && lpnrw->lpLocalName) ||
  12007. (!lpUserNameAnsi && lpUserName) ||
  12008. (!lpPasswordAnsi && lpPassword))
  12009. {
  12010. SetLastError(ERROR_STACK_OVERFLOW);
  12011. return(ERROR_EXTENDED_ERROR);
  12012. }
  12013. return(WNetAddConnection2A(&nra, lpPasswordAnsi, lpUserNameAnsi, dwFlags));
  12014. }
  12015. End=
  12016. [EFunc]
  12017. TemplateName=WNetAddConnection3W
  12018. Begin=
  12019. DWORD __stdcall
  12020. GodotWNetAddConnection3W(HWND hwnd, LPNETRESOURCEW lpnrw, LPCWSTR lpPassword, LPCWSTR lpUser, DWORD dwFlags)
  12021. {
  12022. // Begin locals
  12023. LPSTR lpPasswordAnsi;
  12024. LPSTR lpUserNameAnsi;
  12025. NETRESOURCEA nra;
  12026. // Begin precall
  12027. ZeroMemory(&nra, sizeof(NETRESOURCEA));
  12028. memcpy(&nra, lpnrw, (4*sizeof(DWORD)));
  12029. GODOT_TO_ACP_STACKALLOC(lpnrw->lpLocalName, nra.lpLocalName);
  12030. GODOT_TO_ACP_STACKALLOC(lpnrw->lpRemoteName, nra.lpRemoteName);
  12031. GODOT_TO_ACP_STACKALLOC(lpnrw->lpComment, nra.lpComment);
  12032. GODOT_TO_ACP_STACKALLOC(lpnrw->lpProvider, nra.lpProvider);
  12033. GODOT_TO_ACP_STACKALLOC(lpUser, lpUserNameAnsi);
  12034. GODOT_TO_ACP_STACKALLOC(lpPassword, lpPasswordAnsi);
  12035. if((!nra.lpLocalName && lpnrw->lpLocalName) ||
  12036. (!nra.lpLocalName && lpnrw->lpLocalName) ||
  12037. (!nra.lpLocalName && lpnrw->lpLocalName) ||
  12038. (!nra.lpLocalName && lpnrw->lpLocalName) ||
  12039. (!lpUserNameAnsi && lpUser) ||
  12040. (!lpPasswordAnsi && lpPassword))
  12041. {
  12042. SetLastError(ERROR_STACK_OVERFLOW);
  12043. return(ERROR_EXTENDED_ERROR);
  12044. }
  12045. return(WNetAddConnection3A(hwnd, &nra, lpPasswordAnsi, lpUserNameAnsi, dwFlags));
  12046. }
  12047. End=
  12048. [EFunc]
  12049. TemplateName=WNetConnectionDialog1W
  12050. Begin=
  12051. DWORD __stdcall
  12052. GodotWNetConnectionDialog1W(LPCONNECTDLGSTRUCTW lpConnDlgStruct)
  12053. {
  12054. // Begin locals
  12055. CONNECTDLGSTRUCTA cdsa;
  12056. // Begin precall
  12057. ZeroMemory(&cdsa, sizeof(CONNECTDLGSTRUCTA));
  12058. cdsa.cbStructure = lpConnDlgStruct->cbStructure;
  12059. cdsa.hwndOwner = lpConnDlgStruct->hwndOwner;
  12060. memcpy(&(cdsa.lpConnRes), lpConnDlgStruct->lpConnRes, (4*sizeof(DWORD)));
  12061. GODOT_TO_ACP_STACKALLOC((lpConnDlgStruct->lpConnRes)->lpLocalName, (cdsa.lpConnRes)->lpLocalName);
  12062. GODOT_TO_ACP_STACKALLOC((lpConnDlgStruct->lpConnRes)->lpRemoteName, (cdsa.lpConnRes)->lpRemoteName);
  12063. GODOT_TO_ACP_STACKALLOC((lpConnDlgStruct->lpConnRes)->lpComment, (cdsa.lpConnRes)->lpComment);
  12064. GODOT_TO_ACP_STACKALLOC((lpConnDlgStruct->lpConnRes)->lpProvider, (cdsa.lpConnRes)->lpProvider);
  12065. if((!(cdsa.lpConnRes)->lpLocalName && (lpConnDlgStruct->lpConnRes)->lpLocalName) ||
  12066. (!(cdsa.lpConnRes)->lpRemoteName && (lpConnDlgStruct->lpConnRes)->lpRemoteName) ||
  12067. (!(cdsa.lpConnRes)->lpComment && (lpConnDlgStruct->lpConnRes)->lpComment) ||
  12068. (!(cdsa.lpConnRes)->lpProvider && (lpConnDlgStruct->lpConnRes)->lpProvider))
  12069. {
  12070. SetLastError(ERROR_STACK_OVERFLOW);
  12071. return(ERROR_EXTENDED_ERROR);
  12072. }
  12073. cdsa.dwFlags = lpConnDlgStruct->dwFlags;
  12074. cdsa.dwDevNum = lpConnDlgStruct->dwDevNum;
  12075. // Call the 'A' version of the API
  12076. return(WNetConnectionDialog1A(&cdsa));
  12077. }
  12078. End=
  12079. [EFunc]
  12080. TemplateName=WNetDisconnectDialog1W
  12081. Begin=
  12082. DWORD __stdcall
  12083. GodotWNetDisconnectDialog1W(LPDISCDLGSTRUCTW lpConnDlgStruct)
  12084. {
  12085. // Begin locals
  12086. DISCDLGSTRUCTA ddsa;
  12087. // Begin precall
  12088. ZeroMemory(&ddsa, sizeof(DISCDLGSTRUCTA));
  12089. ddsa.cbStructure = lpConnDlgStruct->cbStructure;
  12090. ddsa.hwndOwner = lpConnDlgStruct->hwndOwner;
  12091. ddsa.dwFlags = lpConnDlgStruct->dwFlags;
  12092. GODOT_TO_ACP_STACKALLOC(lpConnDlgStruct->lpLocalName, ddsa.lpLocalName);
  12093. GODOT_TO_ACP_STACKALLOC(lpConnDlgStruct->lpRemoteName, ddsa.lpRemoteName);
  12094. if((!ddsa.lpLocalName && lpConnDlgStruct->lpLocalName) ||
  12095. (!ddsa.lpRemoteName && lpConnDlgStruct->lpRemoteName))
  12096. {
  12097. SetLastError(ERROR_STACK_OVERFLOW);
  12098. return(ERROR_EXTENDED_ERROR);
  12099. }
  12100. // Call the 'A' version of the API
  12101. return(WNetDisconnectDialog1A(&ddsa));
  12102. }
  12103. End=
  12104. [EFunc]
  12105. TemplateName=WNetGetConnectionW
  12106. Begin=
  12107. DWORD __stdcall
  12108. GodotWNetGetConnectionW(LPCWSTR lpLocalName, LPWSTR lpRemoteName, LPDWORD lpnLength)
  12109. {
  12110. // Begin locals
  12111. DWORD RetVal;
  12112. LPSTR lpLocalNameAnsi;
  12113. LPSTR lpRemoteNameAnsi;
  12114. DWORD nLength;
  12115. // Begin precall
  12116. GODOT_TO_ACP_STACKALLOC(lpLocalName, lpLocalNameAnsi);
  12117. if(!lpnLength)
  12118. nLength = 0;
  12119. else
  12120. nLength = (*lpnLength * g_mcs) + 1;
  12121. _STACKALLOC(nLength, lpRemoteNameAnsi);
  12122. RetVal=WNetGetConnectionA(lpLocalNameAnsi, lpRemoteNameAnsi, &nLength);
  12123. if(RetVal==NO_ERROR)
  12124. {
  12125. if(lpnLength)
  12126. {
  12127. MultiByteToWideChar(g_acp, 0, lpRemoteNameAnsi, nLength, lpRemoteName, *lpnLength);
  12128. *lpnLength = gwcslen(lpRemoteName);
  12129. }
  12130. }
  12131. else
  12132. {
  12133. if(lpnLength)
  12134. *lpnLength = nLength;
  12135. }
  12136. // Finished
  12137. return RetVal;
  12138. }
  12139. End=
  12140. [EFunc]
  12141. TemplateName=WNetGetLastErrorW
  12142. Begin=
  12143. DWORD __stdcall
  12144. GodotWNetGetLastErrorW(LPDWORD lpError, LPWSTR lpszError, DWORD cchError, LPWSTR lpszName, DWORD cchName)
  12145. {
  12146. DWORD RetVal;
  12147. LPSTR lpErrorBufAnsi;
  12148. LPSTR lpNameBufAnsi;
  12149. // Begin precall
  12150. _STACKALLOC((cchError*g_mcs)+1, lpErrorBufAnsi);
  12151. _STACKALLOC((cchName*g_mcs)+1, lpNameBufAnsi);
  12152. if((lpErrorBufAnsi==NULL) || (lpNameBufAnsi==NULL))
  12153. {
  12154. SetLastError(ERROR_STACK_OVERFLOW);
  12155. return(0);
  12156. }
  12157. ZeroMemory(lpErrorBufAnsi, (cchError*g_mcs)+1);
  12158. ZeroMemory(lpNameBufAnsi, (cchName*g_mcs)+1);
  12159. RetVal=WNetGetLastErrorA(lpError, lpErrorBufAnsi, cchError, lpNameBufAnsi, cchName);
  12160. if(RetVal==NO_ERROR)
  12161. {
  12162. MultiByteToWideChar(g_acp, 0, lpErrorBufAnsi, -1, lpszError, cchError);
  12163. MultiByteToWideChar(g_acp, 0, lpNameBufAnsi, -1, lpszName, cchName);
  12164. }
  12165. // Finished
  12166. return RetVal;
  12167. }
  12168. End=
  12169. [EFunc]
  12170. TemplateName=WNetGetProviderNameW
  12171. Begin=
  12172. DWORD __stdcall
  12173. GodotWNetGetProviderNameW(DWORD dwNetType, LPWSTR lpProviderName, LPDWORD lpBufferSize)
  12174. {
  12175. // Begin locals
  12176. DWORD RetVal;
  12177. LPSTR lpProviderNameAnsi;
  12178. // Note that the PSDK docs that the buffer must be at least
  12179. // one character.
  12180. if((!lpProviderName) || (!lpBufferSize) || (!(*lpBufferSize)))
  12181. RetVal = ERROR_INVALID_ADDRESS;
  12182. else
  12183. {
  12184. _STACKALLOC((*lpBufferSize + 1)*g_mcs, lpProviderNameAnsi);
  12185. // Call the 'A' version of the API
  12186. RetVal=WNetGetProviderNameA(dwNetType, lpProviderNameAnsi, lpBufferSize);
  12187. // Begin postcall
  12188. if(RetVal==NO_ERROR)
  12189. {
  12190. MultiByteToWideChar(g_acp, 0, lpProviderNameAnsi, -1, lpProviderName, *lpBufferSize);
  12191. }
  12192. else if(RetVal == ERROR_MORE_DATA)
  12193. {
  12194. // We do not know the exact size here, so out best guess is the
  12195. // size of the string. Note that we are getting back bytes here
  12196. // but need to pass back characters. This means we will divide by
  12197. // two on DBCS.
  12198. *lpBufferSize = (*lpBufferSize / g_mcs);
  12199. }
  12200. }
  12201. // Finished
  12202. return RetVal;
  12203. }
  12204. End=
  12205. [EFunc]
  12206. TemplateName=WNetGetResourceInformationW
  12207. Begin=
  12208. DWORD __stdcall
  12209. GodotWNetGetResourceInformationW(LPNETRESOURCEW lpnrw, LPVOID lpBuffer, LPDWORD lpcb, LPWSTR * lplpSystem)
  12210. {
  12211. // Begin locals
  12212. DWORD RetVal;
  12213. NETRESOURCEA nra;
  12214. LPSTR * lplpSystemAnsi = NULL;
  12215. LPVOID lpBufferAnsi;
  12216. LPNETRESOURCEW lprnw;
  12217. LPNETRESOURCEA lpnraOut;
  12218. DWORD dwOffset;
  12219. LPWSTR lpwz;
  12220. size_t cbSystem;
  12221. ZeroMemory(&nra, sizeof(NETRESOURCEA));
  12222. memcpy(&nra, lpnrw, (4*sizeof(DWORD)));
  12223. GODOT_TO_ACP_STACKALLOC(lpnrw->lpLocalName, nra.lpLocalName);
  12224. GODOT_TO_ACP_STACKALLOC(lpnrw->lpRemoteName, nra.lpRemoteName);
  12225. GODOT_TO_ACP_STACKALLOC(lpnrw->lpComment, nra.lpComment);
  12226. GODOT_TO_ACP_STACKALLOC(lpnrw->lpProvider, nra.lpProvider);
  12227. if((!nra.lpLocalName && lpnrw->lpLocalName) ||
  12228. (!nra.lpLocalName && lpnrw->lpLocalName) ||
  12229. (!nra.lpLocalName && lpnrw->lpLocalName) ||
  12230. (!nra.lpLocalName && lpnrw->lpLocalName))
  12231. {
  12232. SetLastError(ERROR_STACK_OVERFLOW);
  12233. return(ERROR_EXTENDED_ERROR);
  12234. }
  12235. // Set up the buffer if there is one, otherwise
  12236. // pass NULLL to try to get a buffer size
  12237. if(lpcb && *lpcb)
  12238. {
  12239. _STACKALLOC(*lpcb, lpBufferAnsi);
  12240. }
  12241. else
  12242. lpBufferAnsi = NULL;
  12243. // Call the 'A' version of the API
  12244. RetVal=WNetGetResourceInformationA(&nra, lpBuffer, lpcb, lplpSystemAnsi);
  12245. // Begin postcall
  12246. if(RetVal==NO_ERROR)
  12247. {
  12248. // Set up our NETRESOURCE vars
  12249. lpnraOut = lpBufferAnsi;
  12250. lprnw = lpBuffer;
  12251. // Copy the first four (non-string) parameters and set the offset
  12252. memcpy(lpnrw, lpnraOut, (4*sizeof(DWORD)));
  12253. dwOffset = sizeof(NETRESOURCEW);
  12254. // Local name
  12255. lpwz = (LPWSTR)&lprnw + dwOffset;
  12256. MultiByteToWideChar(g_acp, 0, lpnraOut->lpLocalName, -1, lpwz, -1);
  12257. dwOffset += (lpwz ? gwcslen(lpwz) + 1 : 0);
  12258. lpnrw->lpLocalName = lpwz;
  12259. // Remote name
  12260. lpwz = (LPWSTR)&lprnw + dwOffset;
  12261. MultiByteToWideChar(g_acp, 0, lpnraOut->lpRemoteName, -1, lpwz, -1);
  12262. dwOffset += (lpwz ? gwcslen(lpwz) + 1 : 0);
  12263. lpnrw->lpRemoteName = lpwz;
  12264. // Comment
  12265. lpwz = (LPWSTR)&lprnw + dwOffset;
  12266. MultiByteToWideChar(g_acp, 0, lpnraOut->lpComment, -1, lpwz, -1);
  12267. dwOffset += (lpwz ? gwcslen(lpwz) + 1 : 0);
  12268. lpnrw->lpComment = lpwz;
  12269. // Provider
  12270. lpwz = (LPWSTR)&lprnw + dwOffset;
  12271. MultiByteToWideChar(g_acp, 0, lpnraOut->lpProvider, -1, lpwz, -1);
  12272. dwOffset += (lpwz ? gwcslen(lpwz) + 1 : 0);
  12273. lpnrw->lpProvider = lpwz;
  12274. if(lplpSystem && lplpSystemAnsi)
  12275. {
  12276. // Now we take care of lplpSystemAnsi. We cannot directly do this, but we
  12277. // can convert it to a temp buffer, search for the string in the caller's
  12278. // lpBuffer with gwcsstr and let it return that pointer if there is one.
  12279. cbSystem = strlen(*lplpSystemAnsi);
  12280. _STACKALLOC((cbSystem * g_mcs) + 1, lpwz);
  12281. MultiByteToWideChar(g_acp, 0, *lplpSystemAnsi, -1, lpwz, cbSystem);
  12282. *lplpSystem = gwcsstr(lpBuffer, lpwz);
  12283. }
  12284. }
  12285. else if (RetVal==ERROR_MORE_DATA && lpcb)
  12286. {
  12287. // We do not know the exact size here, so out best guess is the
  12288. // size of the "A" buffer we get back, *2 for all of the structure
  12289. // past the NETRESOURCEA part.
  12290. *lpcb = (sizeof(NETRESOURCEA) +
  12291. ((*lpcb - (sizeof(NETRESOURCEA))) * sizeof(WCHAR)));
  12292. }
  12293. // Finished
  12294. return RetVal;
  12295. }
  12296. End=
  12297. [EFunc]
  12298. TemplateName=WNetGetResourceParentW
  12299. Begin=
  12300. DWORD __stdcall
  12301. GodotWNetGetResourceParentW(LPNETRESOURCEW lpnrw, LPVOID lpBuffer, LPDWORD lpcbBuffer)
  12302. {
  12303. // Begin locals
  12304. DWORD RetVal;
  12305. NETRESOURCEA nra;
  12306. LPVOID lpBufferAnsi;
  12307. LPNETRESOURCEW lprnw;
  12308. LPNETRESOURCEA lpnraOut;
  12309. DWORD dwOffset;
  12310. LPWSTR lpwz;
  12311. // Begin precall
  12312. ZeroMemory(&nra, sizeof(NETRESOURCEA));
  12313. memcpy(&nra, lpnrw, (4*sizeof(DWORD)));
  12314. GODOT_TO_ACP_STACKALLOC(lpnrw->lpLocalName, nra.lpLocalName);
  12315. GODOT_TO_ACP_STACKALLOC(lpnrw->lpRemoteName, nra.lpRemoteName);
  12316. GODOT_TO_ACP_STACKALLOC(lpnrw->lpComment, nra.lpComment);
  12317. GODOT_TO_ACP_STACKALLOC(lpnrw->lpProvider, nra.lpProvider);
  12318. if((!nra.lpLocalName && lpnrw->lpLocalName) ||
  12319. (!nra.lpLocalName && lpnrw->lpLocalName) ||
  12320. (!nra.lpLocalName && lpnrw->lpLocalName) ||
  12321. (!nra.lpLocalName && lpnrw->lpLocalName))
  12322. {
  12323. SetLastError(ERROR_STACK_OVERFLOW);
  12324. return(ERROR_EXTENDED_ERROR);
  12325. }
  12326. // Set up the buffer if there is one, otherwise
  12327. // pass NULL to try to get a buffer size
  12328. if(lpcbBuffer && *lpcbBuffer)
  12329. {
  12330. _STACKALLOC(*lpcbBuffer, lpBufferAnsi);
  12331. if(lpBufferAnsi==NULL)
  12332. {
  12333. return(ERROR_STACK_OVERFLOW);
  12334. }
  12335. }
  12336. else
  12337. lpBufferAnsi = NULL;
  12338. // Call the API
  12339. RetVal=WNetGetResourceParentA(&nra, lpBufferAnsi, lpcbBuffer);
  12340. // Begin postcall
  12341. if(RetVal==NO_ERROR)
  12342. {
  12343. // Set up our NETRESOURCE vars, a valid lpBufferAnsi is implied here
  12344. lpnraOut = lpBufferAnsi;
  12345. lprnw = lpBuffer;
  12346. // Copy the first four (non-string) parameters and set the offset
  12347. memcpy(lpnrw, lpnraOut, (4*sizeof(DWORD)));
  12348. dwOffset = sizeof(NETRESOURCEW);
  12349. // Local name
  12350. if(FSTRING_VALID(lpnraOut->lpLocalName))
  12351. {
  12352. lpwz = (LPWSTR)&lprnw + dwOffset;
  12353. MultiByteToWideChar(g_acp, 0, lpnraOut->lpLocalName, -1, lpwz, -1);
  12354. dwOffset += (lpwz ? gwcslen(lpwz) + 1 : 0);
  12355. lpnrw->lpLocalName = lpwz;
  12356. }
  12357. // Remote name
  12358. if(FSTRING_VALID(lpnraOut->lpRemoteName))
  12359. {
  12360. lpwz = (LPWSTR)&lprnw + dwOffset;
  12361. MultiByteToWideChar(g_acp, 0, lpnraOut->lpRemoteName, -1, lpwz, -1);
  12362. dwOffset += (lpwz ? gwcslen(lpwz) + 1 : 0);
  12363. lpnrw->lpRemoteName = lpwz;
  12364. }
  12365. // Comment
  12366. if(FSTRING_VALID(lpnraOut->lpComment))
  12367. {
  12368. lpwz = (LPWSTR)&lprnw + dwOffset;
  12369. MultiByteToWideChar(g_acp, 0, lpnraOut->lpComment, -1, lpwz, -1);
  12370. dwOffset += (lpwz ? gwcslen(lpwz) + 1 : 0);
  12371. lpnrw->lpComment = lpwz;
  12372. }
  12373. // Provider
  12374. if(FSTRING_VALID(lpnraOut->lpProvider))
  12375. {
  12376. lpwz = (LPWSTR)&lprnw + dwOffset;
  12377. MultiByteToWideChar(g_acp, 0, lpnraOut->lpProvider, -1, lpwz, -1);
  12378. dwOffset += (lpwz ? gwcslen(lpwz) + 1 : 0);
  12379. lpnrw->lpProvider = lpwz;
  12380. }
  12381. }
  12382. else if (RetVal==ERROR_MORE_DATA && lpcbBuffer)
  12383. {
  12384. // We do not know the exact size here, so out best guess is the
  12385. // size of the "A" buffer we get back, *2 for all of the structure
  12386. // past the NETRESOURCEA part.
  12387. *lpcbBuffer = (sizeof(NETRESOURCEA) +
  12388. ((*lpcbBuffer - (sizeof(NETRESOURCEA))) * sizeof(WCHAR)));
  12389. }
  12390. // Finished
  12391. return RetVal;
  12392. }
  12393. End=
  12394. [EFunc]
  12395. TemplateName=WNetGetUserW
  12396. Begin=
  12397. DWORD __stdcall
  12398. GodotWNetGetUserW(LPCWSTR lpName, LPWSTR lpUserName, LPDWORD lpnLength)
  12399. {
  12400. DWORD RetVal;
  12401. LPSTR lpNameAnsi;
  12402. LPSTR lpUserNameAnsi;
  12403. DWORD nLength;
  12404. if(!lpnLength)
  12405. {
  12406. SetLastError(ERROR_INVALID_PARAMETER);
  12407. return(0);
  12408. }
  12409. nLength = *lpnLength;
  12410. GODOT_TO_ACP_STACKALLOC(lpName, lpNameAnsi);
  12411. // Alloc buffer, assume caller is being honest about size
  12412. _STACKALLOC((nLength *g_mcs)+1, lpUserNameAnsi);
  12413. RetVal=WNetGetUserA(lpNameAnsi, lpUserNameAnsi, &nLength);
  12414. if(RetVal==WN_NO_ERROR)
  12415. {
  12416. if (*lpnLength >= nLength)
  12417. {
  12418. // Success and buffer was big enough
  12419. MultiByteToWideChar(g_acp, 0, lpUserNameAnsi, nLength, lpUserName, *lpnLength);
  12420. *lpnLength = gwcslen(lpUserName);
  12421. }
  12422. else
  12423. {
  12424. // It was not real success, as their buffer was not large enough
  12425. RetVal=ERROR_MORE_DATA;
  12426. *lpnLength = nLength;
  12427. }
  12428. }
  12429. else
  12430. *lpnLength = nLength;
  12431. // Finished
  12432. return RetVal;
  12433. }
  12434. End=
  12435. [EFunc]
  12436. TemplateName=WNetOpenEnumW
  12437. Begin=
  12438. DWORD __stdcall
  12439. GodotWNetOpenEnumW(DWORD dwScope, DWORD dwType, DWORD dwUsage, LPNETRESOURCEW lpnrw, LPHANDLE lphEnum)
  12440. {
  12441. NETRESOURCEA nra;
  12442. ZeroMemory(&nra, sizeof(NETRESOURCEA));
  12443. memcpy(&nra, lpnrw, (4*sizeof(DWORD)));
  12444. GODOT_TO_ACP_STACKALLOC(lpnrw->lpLocalName, nra.lpLocalName);
  12445. GODOT_TO_ACP_STACKALLOC(lpnrw->lpRemoteName, nra.lpRemoteName);
  12446. GODOT_TO_ACP_STACKALLOC(lpnrw->lpComment, nra.lpComment);
  12447. GODOT_TO_ACP_STACKALLOC(lpnrw->lpProvider, nra.lpProvider);
  12448. if((!nra.lpLocalName && lpnrw->lpLocalName) ||
  12449. (!nra.lpLocalName && lpnrw->lpLocalName) ||
  12450. (!nra.lpLocalName && lpnrw->lpLocalName) ||
  12451. (!nra.lpLocalName && lpnrw->lpLocalName))
  12452. {
  12453. SetLastError(ERROR_STACK_OVERFLOW);
  12454. return(ERROR_EXTENDED_ERROR);
  12455. }
  12456. // Call the 'A' version of the API
  12457. return(WNetOpenEnumA(dwScope, dwType, dwUsage, &nra, lphEnum));
  12458. }
  12459. End=
  12460. [EFunc]
  12461. TemplateName=WNetUseConnectionW
  12462. Begin=
  12463. DWORD __stdcall
  12464. GodotWNetUseConnectionW( HWND hwndOwner,
  12465. LPNETRESOURCEW lpnrw,
  12466. LPCWSTR lpUserID,
  12467. LPCWSTR lpPassword,
  12468. DWORD dwFlags,
  12469. LPWSTR lpAccessName,
  12470. LPDWORD lpBufferSize,
  12471. LPDWORD lpResult
  12472. )
  12473. {
  12474. // Begin locals
  12475. DWORD RetVal;
  12476. LPSTR lpUserIDAnsi;
  12477. LPSTR lpPasswordAnsi;
  12478. NETRESOURCEA nra;
  12479. LPSTR lpAccessNameAnsi;
  12480. // Begin precall
  12481. ZeroMemory(&nra, sizeof(NETRESOURCEA));
  12482. memcpy(&nra, lpnrw, (4*sizeof(DWORD)));
  12483. GODOT_TO_ACP_STACKALLOC(lpnrw->lpLocalName, nra.lpLocalName);
  12484. GODOT_TO_ACP_STACKALLOC(lpnrw->lpRemoteName, nra.lpRemoteName);
  12485. GODOT_TO_ACP_STACKALLOC(lpnrw->lpComment, nra.lpComment);
  12486. GODOT_TO_ACP_STACKALLOC(lpnrw->lpProvider, nra.lpProvider);
  12487. GODOT_TO_ACP_STACKALLOC(lpUserID, lpUserIDAnsi);
  12488. GODOT_TO_ACP_STACKALLOC(lpPassword, lpPasswordAnsi);
  12489. if((!nra.lpLocalName && lpnrw->lpLocalName) ||
  12490. (!nra.lpLocalName && lpnrw->lpLocalName) ||
  12491. (!nra.lpLocalName && lpnrw->lpLocalName) ||
  12492. (!nra.lpLocalName && lpnrw->lpLocalName) ||
  12493. (!lpUserIDAnsi && lpUserID) ||
  12494. (!lpPasswordAnsi && lpPassword))
  12495. {
  12496. SetLastError(ERROR_STACK_OVERFLOW);
  12497. return(ERROR_EXTENDED_ERROR);
  12498. }
  12499. // Alloc buffer, assume caller is being honest about size
  12500. _STACKALLOC((*lpBufferSize*g_mcs)+1, lpAccessNameAnsi);
  12501. // IMPORTANT! Per PSDK: Windows 95/98:
  12502. // The lpUserID and lpPassword parameters are in reverse order from the order used
  12503. // on Windows NT/Windows 2000.
  12504. // Thus, we reverse the order
  12505. RetVal=WNetUseConnectionA(hwndOwner,
  12506. &nra,
  12507. lpPasswordAnsi,
  12508. lpUserIDAnsi,
  12509. dwFlags,
  12510. lpAccessNameAnsi,
  12511. lpBufferSize,
  12512. lpResult
  12513. );
  12514. if(RetVal==NO_ERROR)
  12515. {
  12516. MultiByteToWideChar(g_acp, 0, lpAccessNameAnsi, -1, lpAccessName, *lpBufferSize);
  12517. *lpBufferSize = gwcslen(lpAccessName);
  12518. }
  12519. else if(RetVal==ERROR_MORE_DATA)
  12520. {
  12521. // Since *lpBufferSize is the size in cch, we should be able to live with it
  12522. }
  12523. // Finished
  12524. return RetVal;
  12525. }
  12526. End=
  12527. [EFunc]
  12528. TemplateName=wvsprintfW
  12529. Begin=
  12530. // Stolen from wsprintf.c in the NT sources
  12531. #define WSPRINTF_LIMIT 1024
  12532. const ULONG MAX_ULONG = 0xFFFFFFFF;
  12533. #define MAXULONG MAX_ULONG
  12534. #define out(c) if (cchLimit) {*lpOut++=(c); cchLimit--;} else goto errorout
  12535. int __stdcall
  12536. GodotwvsprintfW(LPWSTR lpOut, LPCWSTR lpFmt, va_list arglist)
  12537. {
  12538. BOOL fAllocateMem;
  12539. WCHAR prefix, fillch;
  12540. int left, width, prec, size, sign, radix, upper, hprefix;
  12541. int cchLimit = WSPRINTF_LIMIT, cch;
  12542. LPWSTR lpT;
  12543. LPWSTR lpTWC = NULL;
  12544. LPBYTE psz;
  12545. va_list varglist = arglist;
  12546. union {
  12547. LONG64 l;
  12548. ULONG64 ul;
  12549. char sz[2];
  12550. WCHAR wsz[2];
  12551. } val;
  12552. while (*lpFmt != 0)
  12553. {
  12554. if (*lpFmt == L'%')
  12555. {
  12556. /*
  12557. * read the flags. These can be in any order
  12558. */
  12559. left = 0;
  12560. prefix = 0;
  12561. while (*++lpFmt)
  12562. {
  12563. if (*lpFmt == L'-')
  12564. left++;
  12565. else if (*lpFmt == L'#')
  12566. prefix++;
  12567. else
  12568. break;
  12569. }
  12570. /*
  12571. * find fill character
  12572. */
  12573. if (*lpFmt == L'0')
  12574. {
  12575. fillch = L'0';
  12576. lpFmt++;
  12577. } else
  12578. fillch = L' ';
  12579. /*
  12580. * read the width specification
  12581. */
  12582. lpFmt = SP_GetFmtValueW(lpFmt, &cch);
  12583. width = cch;
  12584. /*
  12585. * read the precision
  12586. */
  12587. if (*lpFmt == L'.')
  12588. {
  12589. lpFmt = SP_GetFmtValueW(++lpFmt, &cch);
  12590. prec = cch;
  12591. } else
  12592. prec = -1;
  12593. /*
  12594. * get the operand size
  12595. * default size: size == 0
  12596. * long number: size == 1
  12597. * wide chars: size == 2
  12598. * 64bit number: size == 3
  12599. * It may be a good idea to check the value of size when it
  12600. * is tested for non-zero below (IanJa)
  12601. */
  12602. hprefix = 0;
  12603. if ((*lpFmt == L'w') || (*lpFmt == L't'))
  12604. {
  12605. size = 2;
  12606. lpFmt++;
  12607. }
  12608. else if (*lpFmt == L'l')
  12609. {
  12610. size = 1;
  12611. lpFmt++;
  12612. }
  12613. else if (*lpFmt == L'I')
  12614. {
  12615. if (*(lpFmt+1) == L'3' && *(lpFmt+2) == L'2')
  12616. {
  12617. size = 1;
  12618. lpFmt += 3;
  12619. }
  12620. else if (*(lpFmt+1) == L'6' && *(lpFmt+2) == L'4')
  12621. {
  12622. size = 3;
  12623. lpFmt += 3;
  12624. }
  12625. else
  12626. {
  12627. size = (sizeof(INT_PTR) == sizeof(LONG)) ? 1 : 3;
  12628. lpFmt++;
  12629. }
  12630. }
  12631. else
  12632. {
  12633. size = 0;
  12634. if (*lpFmt == L'h')
  12635. {
  12636. lpFmt++;
  12637. hprefix = 1;
  12638. }
  12639. else if ((*lpFmt == L'i') || (*lpFmt == L'd'))
  12640. {
  12641. // %i or %d specified (no modifiers) - use long
  12642. // %u seems to have always been short - leave alone
  12643. size = 1;
  12644. }
  12645. }
  12646. upper = 0;
  12647. sign = 0;
  12648. radix = 10;
  12649. switch (*lpFmt)
  12650. {
  12651. case 0:
  12652. goto errorout;
  12653. case L'i':
  12654. case L'd':
  12655. sign++;
  12656. /*** FALL THROUGH to case 'u' ***/
  12657. case L'u':
  12658. /* turn off prefix if decimal */
  12659. prefix = 0;
  12660. donumeric:
  12661. /* special cases to act like MSC v5.10 */
  12662. if (left || prec >= 0)
  12663. fillch = L' ';
  12664. /*
  12665. * if size == 1, "%lu" was specified (good);
  12666. * if size == 2, "%wu" was specified (bad)
  12667. * if size == 3, "%p" was specified
  12668. */
  12669. if (size == 3)
  12670. {
  12671. val.l = va_arg(varglist, LONG64);
  12672. }
  12673. else if (size)
  12674. {
  12675. val.l = va_arg(varglist, LONG);
  12676. }
  12677. else if (sign)
  12678. {
  12679. val.l = va_arg(varglist, SHORT);
  12680. }
  12681. else
  12682. {
  12683. val.ul = va_arg(varglist, unsigned);
  12684. }
  12685. if (sign && val.l < 0L)
  12686. val.l = -val.l;
  12687. else
  12688. sign = 0;
  12689. /*
  12690. * Unless printing a full 64-bit value, ensure values
  12691. * here are not in canonical longword format to prevent
  12692. * the sign extended upper 32-bits from being printed.
  12693. */
  12694. if (size != 3)
  12695. {
  12696. val.l &= MAXULONG;
  12697. }
  12698. lpT = lpOut;
  12699. /*
  12700. * blast the number backwards into the user buffer
  12701. */
  12702. cch = SP_PutNumberW(lpOut, val.l, cchLimit, radix, upper);
  12703. if (!(cchLimit -= cch))
  12704. goto errorout;
  12705. lpOut += cch;
  12706. width -= cch;
  12707. prec -= cch;
  12708. if (prec > 0)
  12709. width -= prec;
  12710. /*
  12711. * fill to the field precision
  12712. */
  12713. while (prec-- > 0)
  12714. out(L'0');
  12715. if (width > 0 && !left)
  12716. {
  12717. /*
  12718. * if we're filling with spaces, put sign first
  12719. */
  12720. if (fillch != L'0')
  12721. {
  12722. if (sign)
  12723. {
  12724. sign = 0;
  12725. out(L'-');
  12726. width--;
  12727. }
  12728. if (prefix)
  12729. {
  12730. out(prefix);
  12731. out(L'0');
  12732. prefix = 0;
  12733. }
  12734. }
  12735. if (sign)
  12736. width--;
  12737. /*
  12738. * fill to the field width
  12739. */
  12740. while (width-- > 0)
  12741. out(fillch);
  12742. /*
  12743. * still have a sign?
  12744. */
  12745. if (sign)
  12746. out(L'-');
  12747. if (prefix)
  12748. {
  12749. out(prefix);
  12750. out(L'0');
  12751. }
  12752. /*
  12753. * now reverse the string in place
  12754. */
  12755. SP_ReverseW(lpT, lpOut - 1);
  12756. }
  12757. else
  12758. {
  12759. /*
  12760. * add the sign character
  12761. */
  12762. if (sign)
  12763. {
  12764. out(L'-');
  12765. width--;
  12766. }
  12767. if (prefix)
  12768. {
  12769. out(prefix);
  12770. out(L'0');
  12771. }
  12772. /*
  12773. * reverse the string in place
  12774. */
  12775. SP_ReverseW(lpT, lpOut - 1);
  12776. /*
  12777. * pad to the right of the string in case left aligned
  12778. */
  12779. while (width-- > 0)
  12780. out(fillch);
  12781. }
  12782. break;
  12783. case L'p':
  12784. size = (sizeof(PVOID) == sizeof(LONG)) ? 1 : 3;
  12785. if (prec == -1)
  12786. {
  12787. prec = 2 * sizeof(PVOID);
  12788. }
  12789. /*** FALL THROUGH to case 'X' ***/
  12790. case L'X':
  12791. upper++;
  12792. /*** FALL THROUGH to case 'x' ***/
  12793. case L'x':
  12794. radix = 16;
  12795. if (prefix)
  12796. if (upper)
  12797. prefix = L'X';
  12798. else
  12799. prefix = L'x';
  12800. goto donumeric;
  12801. case L'c':
  12802. if (!size && !hprefix)
  12803. {
  12804. size = 1; // force WCHAR
  12805. }
  12806. /*** FALL THROUGH to case 'C' ***/
  12807. case L'C':
  12808. /*
  12809. * if size == 0, "%C" or "%hc" was specified (CHAR);
  12810. * if size == 1, "%c" or "%lc" was specified (WCHAR);
  12811. * if size == 2, "%wc" or "%tc" was specified (WCHAR)
  12812. */
  12813. cch = 1; /* One character must be copied to the output buffer */
  12814. if (size)
  12815. {
  12816. val.wsz[0] = va_arg(varglist, WCHAR);
  12817. val.wsz[1] = 0;
  12818. lpT = val.wsz;
  12819. goto putwstring;
  12820. }
  12821. else
  12822. {
  12823. val.sz[0] = va_arg(varglist, CHAR);
  12824. val.sz[1] = 0;
  12825. psz = (LPBYTE)val.sz;
  12826. goto putstring;
  12827. }
  12828. case L's':
  12829. if (!size && !hprefix)
  12830. {
  12831. size = 1; // force LPWSTR
  12832. }
  12833. /*** FALL THROUGH to case 'S' ***/
  12834. case L'S':
  12835. /*
  12836. * if size == 0, "%S" or "%hs" was specified (LPSTR)
  12837. * if size == 1, "%s" or "%ls" was specified (LPWSTR);
  12838. * if size == 2, "%ws" or "%ts" was specified (LPWSTR)
  12839. */
  12840. if (size)
  12841. {
  12842. lpT = va_arg(varglist, LPWSTR);
  12843. cch = gwcslen(lpT);
  12844. putwstring:
  12845. fAllocateMem = FALSE;
  12846. }
  12847. else
  12848. {
  12849. psz = va_arg(varglist, LPBYTE);
  12850. if (psz == NULL)
  12851. {
  12852. cch = 0;
  12853. }
  12854. else
  12855. {
  12856. cch = strlen((LPSTR)psz);
  12857. }
  12858. putstring:
  12859. lpTWC = GodotHeapAlloc(cch * sizeof(WCHAR));
  12860. if(lpTWC)
  12861. {
  12862. cch = MultiByteToWideChar(g_acp, 0, (LPSTR)psz, cch, lpTWC, cch);
  12863. fAllocateMem = TRUE;
  12864. }
  12865. else
  12866. {
  12867. cch = 0;
  12868. fAllocateMem = FALSE;
  12869. }
  12870. lpT = lpTWC;
  12871. }
  12872. if (prec >= 0 && cch > prec)
  12873. cch = prec;
  12874. width -= cch;
  12875. if (fAllocateMem)
  12876. {
  12877. if (cch + (width < 0 ? 0 : width) >= cchLimit)
  12878. {
  12879. GodotHeapFree(lpTWC);
  12880. goto errorout;
  12881. }
  12882. }
  12883. if (left)
  12884. {
  12885. while (cch--)
  12886. out(*lpT++);
  12887. while (width-- > 0)
  12888. out(fillch);
  12889. }
  12890. else
  12891. {
  12892. while (width-- > 0)
  12893. out(fillch);
  12894. while (cch--)
  12895. out(*lpT++);
  12896. }
  12897. if (fAllocateMem)
  12898. {
  12899. GodotHeapFree(lpTWC);
  12900. }
  12901. break;
  12902. default:
  12903. normalch:
  12904. out((WCHAR)*lpFmt);
  12905. break;
  12906. } /* END OF SWITCH(*lpFmt) */
  12907. } /* END OF IF(%) */
  12908. else
  12909. goto normalch; /* character not a '%', just do it */
  12910. /*
  12911. * advance to next format string character
  12912. */
  12913. lpFmt++;
  12914. } /* END OF OUTER WHILE LOOP */
  12915. errorout:
  12916. *lpOut = 0;
  12917. return WSPRINTF_LIMIT - cchLimit;
  12918. }
  12919. End=
  12920. [EFunc]
  12921. TemplateName=wsprintfW
  12922. Begin=
  12923. int _cdecl
  12924. GodotwsprintfW(LPWSTR lpOut, LPCWSTR lpFmt, ... )
  12925. {
  12926. va_list arglist;
  12927. int RetVal;
  12928. va_start(arglist, lpFmt);
  12929. RetVal = GodotwvsprintfW(lpOut, lpFmt, arglist);
  12930. va_end(arglist);
  12931. return RetVal;
  12932. }
  12933. End=