15254 lines
446 KiB
Smarty
15254 lines
446 KiB
Smarty
;;/*++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
;;
|
|
;; Copyright (c) 2000-2001, Microsoft Corporation All rights reserved.
|
|
;;
|
|
;; Module Name:
|
|
;;
|
|
;; unicows.tpl
|
|
;;
|
|
;; Abstract:
|
|
;;
|
|
;; The 'Template' file that drives genthnk. It contains all of the functions to
|
|
;; handle out params and such -- anything not automatable by genthnk.
|
|
;;
|
|
;; Revision History:
|
|
;;
|
|
;; 7 Nov 2000 v-michka Created.
|
|
;;
|
|
;;-------------------------------------------------*/
|
|
|
|
; // This template is a [Code] template. It is expanded by genthnk once
|
|
; // via the -cTemplateName command-line option. Stuff inside the Begin=
|
|
; // End= section is C code or genthnk macros which are prefixed by an 'at' char.
|
|
; //
|
|
[Code]
|
|
TemplateName=UnicodeWrappers
|
|
Begin=
|
|
@NoFormat(
|
|
/*++
|
|
|
|
Copyright (c) 2000-2001, Microsoft Corporation All rights reserved.
|
|
|
|
Module Name:
|
|
|
|
Win9xU.c (Windows 9x Unicode wrapper functions)
|
|
|
|
Abstract:
|
|
|
|
Auto-generated file that contains the thunks.
|
|
|
|
WARNING: Do not edit! This file is auto-generated by getthnk.
|
|
See unicows.tpl if you want to make changes.
|
|
|
|
Revision History:
|
|
|
|
7 Nov 2000 v-michka Created.
|
|
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
|
|
// work around thick-skulled genthnk. It wants ApiName to expand to the
|
|
// name of the original Ansi API. We want to call the Ansi API by
|
|
// appending "A". So... from makefile.inc we generate a bunch of #defines
|
|
// of the form:
|
|
// #define AddAtomWA AddAtomA
|
|
// then from the .tpl file we can use ApiNameA to generate AddAtomWA for
|
|
// the AddAtomW API thunk and get it expanded to the right thing.
|
|
#include "fixaw.h"
|
|
|
|
// A few globals: set on startup and used everywhere thereafter
|
|
// We init these vars with some nice defaults; they *will* be fixed later
|
|
UINT g_acp = CP_ACP; // CP_ACP; it is faster to call with the actual cpg than the CP_ACP const
|
|
UINT g_oemcp = CP_OEMCP; // CP_OEMCP; it is faster to call with the actual cpg than the CP_OEMCP const
|
|
UINT g_mcs = 2; // The maximum character size (in bytes) of a character on CP_ACP
|
|
DWORD g_dwVersion = 0x80000001; // The return from GetVersion, used many places
|
|
|
|
// VSANSI comments:
|
|
// Static buffers for GetClassInfo[Ex] to return the classname
|
|
// and menuname in Unicode, when running on an Ansi system.
|
|
// The contract of GetClassInfo is that it returns const ptrs
|
|
// back to the class name and menu name. Unfortuntely, this
|
|
// prevents us from translating these back from Ansi to Unicode,
|
|
// without having some static buffers to use. Since we strongly
|
|
// believe that the only people calling this are doing it just to
|
|
// see if it succeeds or not, so they know whether the class is
|
|
// already registered, we've willing to just have one set of
|
|
// static buffers to use.
|
|
// CAUTION: this will work as long as two threads don't call
|
|
// GetClassInfo[Ex] at the same time!
|
|
static WCHAR m_wzMenuName[256];
|
|
static WCHAR m_wzClassName[256];
|
|
|
|
// Similar buffers for the strings returned by GetStartupInfo
|
|
// Note that these two buffers are not really hacks; on NT, there
|
|
// is a permanent buffer set aside for the ANSI version of this
|
|
// call, per process. So we are no worse for doing the same thing
|
|
// here for Win9x.
|
|
static WCHAR m_wzDesktop[256];
|
|
static WCHAR m_wzTitle[256];
|
|
|
|
// The Ver* APIs are not very helpful to us since we have no place
|
|
// from which to alloc pointers to Unicode strings. Therefore, we
|
|
// will add a small area to the front of any GetFileVersionInfoSize
|
|
// call that we can use. Note that this means that the calls to
|
|
// VerQueryValue will erase the data from earlier calls, but we can't
|
|
// pull the memory out of our butt, either.
|
|
#define VERINFO_BUFFER (MAX_PATH * sizeof(WCHAR))
|
|
|
|
// For FormatMessageW:
|
|
// We will support a max of 99 arguments, up to 1023 cch per arg
|
|
#define MAXINSERTS 99
|
|
#define CCHMAXPERINSERT 1023
|
|
|
|
// Need a few intrinsics
|
|
#pragma intrinsic (strlen, strcmp, memcpy)
|
|
|
|
// We have no header file, so lets add forward declares for any Godot
|
|
// function that is used by other functions
|
|
BOOL __stdcall GodotExtTextOutW(HDC hdc,int X,int Y,UINT fuOptions,const LPRECT lprc,LPCWSTR lpString,UINT cbCount,const PINT lpDx);
|
|
HRSRC __stdcall GodotFindResourceExW(HMODULE hModule, LPCWSTR lpType, LPCWSTR lpName, WORD wLanguage);
|
|
BOOL __stdcall GodotGetCharWidthW(HDC hdc,UINT iFirstChar,UINT iLastChar,LPINT lpBuffer);
|
|
BOOL __stdcall GodotGetMonitorInfoW(HMONITOR hMonitor, LPMONITORINFO lpmi);
|
|
BOOL __stdcall GodotIsClipboardFormatAvailable(UINT format);
|
|
int __stdcall GodotwvsprintfW(LPWSTR lpOut, LPCWSTR lpFmt, va_list arglist);
|
|
|
|
// Functions we dynamically link to since they might not exist on all
|
|
// platforms that Godot runs upon. First the typdefs, then the function
|
|
// pointers themselves will follow.
|
|
typedef LONG (__stdcall *PFNcdsea) (LPCSTR, LPDEVMODEA, HWND, DWORD, LPVOID);
|
|
typedef BOOL (__stdcall *PFNcfea) (LPCSTR, LPCSTR, LPPROGRESS_ROUTINE, LPVOID, LPBOOL, DWORD);
|
|
typedef HRESULT (__stdcall *PFNcsapa) (HWND, LPCSTR, LONG, const IID *, void **);
|
|
typedef HANDLE (__stdcall *PFNcwta) (LPSECURITY_ATTRIBUTES, BOOL, LPCSTR);
|
|
typedef BOOL (__stdcall *PFNeciea) (CALINFO_ENUMPROCEXA, LCID, CALID, CALTYPE);
|
|
typedef BOOL (__stdcall *PFNedfea) (DATEFMT_ENUMPROCEXA, LCID, DWORD);
|
|
typedef BOOL (__stdcall *PFNedda) (LPCSTR, DWORD, PDISPLAY_DEVICEA, DWORD);
|
|
typedef BOOL (__stdcall *PFNedsea) (LPCSTR, DWORD, LPDEVMODEA, DWORD);
|
|
typedef BOOL (__stdcall *PFNgatia) (HWND, int, PALTTABINFO, LPSTR, UINT);
|
|
typedef BOOL (__stdcall *PFNgcia) (LCID, CALID, CALTYPE, LPSTR, int, LPDWORD);
|
|
typedef BOOL (__stdcall *PFNgciea) (UINT, DWORD, LPCPINFOEXA);
|
|
typedef BOOL (__stdcall *PFNgchpa) (LPHW_PROFILE_INFOA);
|
|
typedef BOOL (__stdcall *PFNgdfsea) (LPCSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER);
|
|
typedef BOOL (__stdcall *PFNgfnaea) (LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
|
|
typedef BOOL (__stdcall *PFNglpna) (LPCSTR, LPSTR, DWORD);
|
|
typedef BOOL (__stdcall *PFNgmia) (HMONITOR, LPMONITORINFO);
|
|
typedef HRESULT (__stdcall *PFNrgta) (DWORD, LPSTR, UINT);
|
|
typedef HRESULT (__stdcall *PFNgsta) (DWORD, LPSTR, UINT);
|
|
typedef UINT (__stdcall *PFNgwmfna) (HWND, LPSTR, UINT);
|
|
typedef BOOL (__stdcall *pfnIDRA) (LPCSTR, LPQOCINFO);
|
|
typedef HANDLE (__stdcall *PFNowta) (DWORD, BOOL, LPCSTR);
|
|
typedef DWORD (__stdcall *pfnRCN) (HRASCONN, HANDLE, DWORD);
|
|
typedef DWORD (__stdcall *pfnRCPE) (HWND, LPCSTR);
|
|
typedef DWORD (__stdcall *pfnRDE) (LPCSTR, LPCSTR);
|
|
typedef DWORD (__stdcall *pfnRDSE) (LPCSTR, LPCSTR, DWORD);
|
|
typedef DWORD (__stdcall *pfnRD) (LPRASDIALEXTENSIONS, LPCSTR, LPRASDIALPARAMSA, DWORD, LPVOID, LPHRASCONN);
|
|
typedef DWORD (__stdcall *pfnREPE) (HWND, LPCSTR, LPCSTR);
|
|
typedef DWORD (__stdcall *pfnREC) (struct tagRASCONNA * , LPDWORD, LPDWORD);
|
|
typedef DWORD (__stdcall *pfnRED) (LPRASDEVINFOA, LPDWORD, LPDWORD);
|
|
typedef DWORD (__stdcall *pfnREE) (LPCSTR, LPCSTR, LPRASENTRYNAMEA, LPDWORD, LPDWORD);
|
|
typedef DWORD (__stdcall *pfnRGCS) (HRASCONN, LPRASCONNSTATUSA);
|
|
typedef DWORD (__stdcall *pfnRGEDP) (LPCSTR, LPRASDIALPARAMSA, LPBOOL);
|
|
typedef DWORD (__stdcall *pfnRGEP) (LPCSTR, LPCSTR, LPRASENTRYA, LPDWORD, LPBYTE, LPDWORD);
|
|
typedef DWORD (__stdcall *pfnRGES) (UINT, LPSTR, DWORD);
|
|
typedef DWORD (__stdcall *pfnRHU) (HRASCONN);
|
|
typedef DWORD (__stdcall *pfnRRE) (LPCSTR, LPCSTR, LPCSTR);
|
|
typedef DWORD (__stdcall *pfnRSEDP) (LPCSTR, LPRASDIALPARAMSA, BOOL);
|
|
typedef DWORD (__stdcall *pfnRSEP) (LPCSTR, LPCSTR, LPRASENTRYA, DWORD, LPBYTE, DWORD);
|
|
typedef DWORD (__stdcall *pfnRSSEP) (LPCSTR, LPCSTR, DWORD, LPRASSUBENTRYA, DWORD, LPBYTE, DWORD);
|
|
typedef DWORD (__stdcall *pfnRVEN) (LPCSTR, LPCSTR);
|
|
typedef HDEVNOTIFY (__stdcall *PFNrdna) (HANDLE, LPVOID, DWORD);
|
|
typedef BOOL (__stdcall *PFNscia) (LCID, CALID, CALTYPE, LPCSTR);
|
|
|
|
static PFNcdsea s_pfnChangeDisplaySettingsExA;
|
|
static PFNcfea s_pfnCopyFileExA;
|
|
static PFNcsapa s_pfnCreateStdAccessibleProxy;
|
|
static PFNcwta s_pfnCreateWaitableTimerA;
|
|
static PFNeciea s_pfnEnumCalendarInfoExA;
|
|
static PFNedfea s_pfnEnumDateFormatsExA;
|
|
static PFNedda s_pfnEnumDisplayDevicesA;
|
|
static PFNedsea s_pfnEnumDisplaySettingsExA;
|
|
static PFNgatia s_pfnGetAltTabInfoA;
|
|
static PFNgcia s_pfnGetCalendarInfoA;
|
|
static PFNgciea s_pfnGetCPInfoExA;
|
|
static PFNgchpa s_pfnGetCurrentHwProfileA;
|
|
static PFNgdfsea s_pfnGetDiskFreeSpaceExA;
|
|
static PFNgfnaea s_pfnGetFileAttributesExA;
|
|
static PFNglpna s_pfnGetLongPathNameA;
|
|
static PFNgmia s_pfnGetMonitorInfoA;
|
|
static PFNrgta s_pfnGetRoleTextA;
|
|
static PFNgsta s_pfnGetStateTextA;
|
|
static PFNgwmfna s_pfnGetWindowModuleFileNameA;
|
|
static pfnIDRA s_pfnIsDestinationReachableA;
|
|
static PFNowta s_pfnOpenWaitableTimerA;
|
|
static pfnRCN s_pfnRasConnectionNotificationA;
|
|
static pfnRCPE s_pfnRasCreatePhonebookEntryA;
|
|
static pfnRDE s_pfnRasDeleteEntryA;
|
|
static pfnRDSE s_pfnRasDeleteSubEntryA;
|
|
static pfnRD s_pfnRasDialA;
|
|
static pfnREPE s_pfnRasEditPhonebookEntryA;
|
|
static pfnREC s_pfnRasEnumConnectionsA;
|
|
static pfnRED s_pfnRasEnumDevicesA;
|
|
static pfnREE s_pfnRasEnumEntriesA;
|
|
static pfnRGCS s_pfnRasGetConnectStatusA;
|
|
static pfnRGEDP s_pfnRasGetEntryDialParamsA;
|
|
static pfnRGEP s_pfnRasGetEntryPropertiesA;
|
|
static pfnRGES s_pfnRasGetErrorStringA;
|
|
static pfnRHU s_pfnRasHangUpA;
|
|
static pfnRRE s_pfnRasRenameEntryA;
|
|
static pfnRSEDP s_pfnRasSetEntryDialParamsA;
|
|
static pfnRSEP s_pfnRasSetEntryPropertiesA;
|
|
static pfnRSSEP s_pfnRasSetSubEntryPropertiesA;
|
|
static pfnRVEN s_pfnRasValidateEntryNameA;
|
|
static PFNrdna s_pfnRegisterDeviceNotificationA;
|
|
static PFNscia s_pfnSetCalendarInfoA;
|
|
|
|
|
|
BOOL WINAPI
|
|
DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
|
{
|
|
// Perform actions based on the reason for calling.
|
|
switch(fdwReason)
|
|
{
|
|
case DLL_PROCESS_ATTACH:
|
|
g_tls = TlsAlloc();
|
|
if (g_tls==TLS_OUT_OF_INDEXES)
|
|
{
|
|
// We are gonna go no further, we NEED that slot!
|
|
// CONSIDER: Let us succeeed, but maybe we could try again later?
|
|
SetLastError(ERROR_MAX_THRDS_REACHED);
|
|
return(FALSE);
|
|
}
|
|
|
|
// CONSIDER: Can't this raise a STATUS_NO_MEMORY exception?
|
|
// Perhaps we need to handle this
|
|
InitializeCriticalSection(&g_csThreads);
|
|
InitializeCriticalSection(&g_csWnds);
|
|
|
|
// Set up some global information used elsewhere. No InterlockedExchange
|
|
// is needed for these globals since the code is only ever called once
|
|
// per process, and calls to DllMain are serialized by the OS, anyway.
|
|
g_acp = GetACP();
|
|
g_oemcp = GetOEMCP();
|
|
g_dwVersion = GetVersion();
|
|
g_mcs = CbPerChOfCpg(g_acp);
|
|
break;
|
|
|
|
case DLL_THREAD_ATTACH:
|
|
break;
|
|
|
|
case DLL_THREAD_DETACH:
|
|
// Any time we get this notification, make sure
|
|
// we free up our resources. If all else fails
|
|
// we will get it on process close, but why not
|
|
// try to get it here?
|
|
UninitThread();
|
|
break;
|
|
|
|
case DLL_PROCESS_DETACH:
|
|
if(g_tls)
|
|
{
|
|
// Free up our resources, if any
|
|
UninitAllThreads();
|
|
|
|
// Clean up the TLS
|
|
TlsFree(g_tls);
|
|
}
|
|
|
|
// free up our critical sections
|
|
if(&g_csThreads)
|
|
DeleteCriticalSection(&g_csThreads);
|
|
if(&g_csWnds)
|
|
DeleteCriticalSection(&g_csWnds);
|
|
|
|
break;
|
|
}
|
|
return TRUE;
|
|
UNREFERENCED_PARAMETER(hinstDLL);
|
|
UNREFERENCED_PARAMETER(lpvReserved);
|
|
}
|
|
|
|
@Template(ApiWrapper)
|
|
|
|
End=
|
|
|
|
; // These templates are [Types] templates. They are expanded whenever
|
|
; // an API argument type matches.
|
|
; // ArgName - name of the argument
|
|
[Types]
|
|
TypeName=LPWSTR
|
|
Also=LPCWSTR
|
|
IndLevel=0
|
|
Direction=IN
|
|
Locals=
|
|
LPSTR @ArgNameAnsi;
|
|
End=
|
|
Precall=
|
|
GODOT_TO_ACP_STACKALLOC(@ArgName, @ArgNameAnsi);
|
|
#define @ArgName @ArgNameAnsi
|
|
End=
|
|
Postcall=
|
|
#undef @ArgName
|
|
End=
|
|
|
|
; //
|
|
; // This template is an [IFunc] template. It is expanded once for each API.
|
|
; // Macros:
|
|
; // ApiName - the name of the API
|
|
; // ArgList() - expands the contents for each argument to the API
|
|
; // ListCol - text formatting - makes a nice column
|
|
; // ArgMod - type modifier like const/volatile
|
|
; // ArgType - type of the argument
|
|
; // ArgName - name of the argument (genthnk will assign a name if the prototype didn't name the arg)
|
|
; // ArgMore() - expands iff there are more args after the current one
|
|
; // IfApiRet() - expands iff the return type of the API is non-void
|
|
; // ApiFnRet - return type of the API
|
|
; // Types() - expands any applicable parts of [Types] templates
|
|
; // IfApiCode() - expands any applicable parts of [EFunc] templates
|
|
; //
|
|
[IFunc]
|
|
TemplateName=ApiWrapper
|
|
Begin=
|
|
@ApiFnRet @ApiFnMod
|
|
Godot@ApiName(@ArgList(@ListCol@ArgMod @ArgType @ArgName@ArgMore(,)))
|
|
{
|
|
// Begin locals
|
|
@IfApiRet(@ApiFnRet RetVal;)
|
|
@Types(Locals)
|
|
@IfApiCode(Locals)
|
|
|
|
// Begin precall
|
|
@Types(Precall)
|
|
@IfApiCode(Precall)
|
|
|
|
// Call the 'A' version of the API
|
|
@IfApiRet(RetVal=)@ApiNameA(@ArgList(@ListCol@ArgName@ArgMore(,)));
|
|
|
|
// Begin postcall
|
|
@Types(Postcall)
|
|
@IfApiCode(Postcall)
|
|
|
|
// Finished
|
|
return @IfApiRet(RetVal);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=AcquireCredentialsHandleW
|
|
Begin=
|
|
SECURITY_STATUS __stdcall
|
|
GodotAcquireCredentialsHandleW( SEC_WCHAR SEC_FAR * pPrincipal,
|
|
SEC_WCHAR SEC_FAR * pPackage,
|
|
unsigned long int fCredentialUse,
|
|
void * pvLogonId,
|
|
void * pAuthData,
|
|
SEC_GET_KEY_FN pGetKeyFn,
|
|
void * pvGetKeyArgument,
|
|
PCredHandle phCredential,
|
|
PTimeStamp ptsExpiry
|
|
)
|
|
{
|
|
// ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
|
|
return(SEC_E_UNSUPPORTED_FUNCTION);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=AddJobW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotAddJobW(HANDLE hPrinter, DWORD Level, LPBYTE pData, DWORD cbBuf, LPDWORD pcbNeeded)
|
|
{
|
|
// Begin locals
|
|
BOOL RetVal;
|
|
LPADDJOB_INFO_1A lpajia;
|
|
LPADDJOB_INFO_1W lpaji;
|
|
|
|
if(Level != 1)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return(FALSE);
|
|
}
|
|
|
|
if(cbBuf == 0)
|
|
SetLastError(ERROR_INVALID_USER_BUFFER);
|
|
|
|
if((cbBuf == 0) || (cbBuf < (sizeof(ADDJOB_INFO_1W) + MAX_PATH * sizeof(WCHAR))))
|
|
{
|
|
if(pcbNeeded)
|
|
*pcbNeeded = (sizeof(ADDJOB_INFO_1W) + MAX_PATH * sizeof(WCHAR));
|
|
return(FALSE);
|
|
}
|
|
|
|
_STACKALLOC(sizeof(ADDJOB_INFO_1A) + (MAX_PATH * g_mcs), lpajia);
|
|
if(lpajia==NULL)
|
|
return(FALSE);
|
|
ZeroMemory(lpajia, sizeof(ADDJOB_INFO_1A) + (MAX_PATH * g_mcs));
|
|
RetVal=AddJobA(hPrinter, Level, (LPBYTE)lpajia, cbBuf, pcbNeeded);
|
|
|
|
if(RetVal)
|
|
{
|
|
lpaji = (LPADDJOB_INFO_1W)pData;
|
|
MultiByteToWideChar(g_acp, 0,
|
|
lpajia->Path, MAX_PATH,
|
|
(LPWSTR)(pData + sizeof(ADDJOB_INFO_1A)), MAX_PATH);
|
|
lpaji->Path = (LPWSTR)(pData + sizeof(ADDJOB_INFO_1A));
|
|
lpaji->JobId = lpajia->JobId;
|
|
if(pcbNeeded)
|
|
*pcbNeeded = (sizeof(ADDJOB_INFO_1W) + MAX_PATH * sizeof(WCHAR));
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=AddMonitorW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotAddMonitorW(LPWSTR pName, DWORD Level, LPBYTE pMonitors)
|
|
{
|
|
if(Level != 2)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return(FALSE);
|
|
}
|
|
else
|
|
{
|
|
LPSTR pNameAnsi;
|
|
MONITOR_INFO_2A mia;
|
|
LPMONITOR_INFO_2W lpmi;
|
|
|
|
// Begin precall
|
|
GODOT_TO_ACP_STACKALLOC(pName, pNameAnsi);
|
|
if(!pNameAnsi && pName)
|
|
{
|
|
return(FALSE);
|
|
}
|
|
ZeroMemory(&mia, sizeof(MONITOR_INFO_2A));
|
|
lpmi = (LPMONITOR_INFO_2W)pMonitors;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lpmi->pName, mia.pName);
|
|
GODOT_TO_ACP_STACKALLOC(lpmi->pEnvironment, mia.pEnvironment);
|
|
GODOT_TO_ACP_STACKALLOC(lpmi->pDLLName, mia.pDLLName);
|
|
if((!(mia.pName) && (lpmi->pName)) ||
|
|
(!(mia.pEnvironment) && (lpmi->pEnvironment)) ||
|
|
(!(mia.pDLLName) && (lpmi->pDLLName)))
|
|
return(FALSE);
|
|
|
|
return(AddMonitorA(pNameAnsi, Level, (LPBYTE)&mia));
|
|
}
|
|
}
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=AddPortW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotAddPortW(LPWSTR pName, HWND hWnd, LPWSTR pMonitorName)
|
|
{
|
|
BOOL RetVal = FALSE;
|
|
LPSTR pNameAnsi = NULL;
|
|
LPSTR pMonitorNameAnsi = NULL;
|
|
ALLOCRETURN arName = GodotToAcpOnHeap(pName, &pNameAnsi);
|
|
ALLOCRETURN arMonitorName = GodotToAcpOnHeap(pMonitorName, &pMonitorNameAnsi);
|
|
|
|
if(arName != arFailed && arMonitorName != arFailed)
|
|
RetVal = AddPortA(pNameAnsi, hWnd, pMonitorNameAnsi);
|
|
|
|
if(arName==arAlloc)
|
|
GodotHeapFree(pNameAnsi);
|
|
if(arMonitorName==arAlloc)
|
|
GodotHeapFree(pMonitorName);
|
|
|
|
if(arName == arFailed || arMonitorName == arFailed)
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=AddPrinterW
|
|
Begin=
|
|
HANDLE __stdcall
|
|
GodotAddPrinterW(LPWSTR pName, DWORD Level, LPBYTE pPrinter)
|
|
{
|
|
LPSTR pNameAnsi;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(pName, pNameAnsi);
|
|
if(pNameAnsi==NULL && pName != NULL)
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
return(AddPrinterA(pNameAnsi, Level, pPrinter));
|
|
}
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=AddPrinterDriverW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotAddPrinterDriverW(LPWSTR pName, DWORD Level, LPBYTE pDriverInfo)
|
|
{
|
|
LPSTR pNameAnsi;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(pName, pNameAnsi);
|
|
if(!pNameAnsi && pName)
|
|
return(FALSE);
|
|
|
|
return(AddPrinterDriverA(pNameAnsi, Level, pDriverInfo));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=AddPrintProcessorW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotAddPrintProcessorW(LPWSTR pName, LPWSTR pEnvironment, LPWSTR pPathName, LPWSTR pPrintProcessorName)
|
|
{
|
|
BOOL RetVal = FALSE;
|
|
LPSTR pNameAnsi = NULL;
|
|
LPSTR pEnvironmentAnsi = NULL;
|
|
LPSTR pPathNameAnsi = NULL;
|
|
LPSTR pPrintProcessorNameAnsi = NULL;
|
|
ALLOCRETURN arName = GodotToAcpOnHeap(pName, &pNameAnsi);
|
|
ALLOCRETURN arEnvironmentName = GodotToAcpOnHeap(pEnvironment, &pEnvironmentAnsi);
|
|
ALLOCRETURN arPathName = GodotToAcpOnHeap(pPathName, &pPathNameAnsi);
|
|
ALLOCRETURN arProcessorName = GodotToAcpOnHeap(pPrintProcessorName, &pPrintProcessorNameAnsi);
|
|
|
|
if(arName != arFailed &&
|
|
arEnvironmentName != arFailed &&
|
|
arPathName != arFailed &&
|
|
arProcessorName != arFailed)
|
|
RetVal = AddPrintProcessorA(pNameAnsi, pEnvironmentAnsi, pPathNameAnsi, pPrintProcessorNameAnsi);
|
|
|
|
if(arName==arAlloc)
|
|
GodotHeapFree(pNameAnsi);
|
|
if(arEnvironmentName==arAlloc)
|
|
GodotHeapFree(pEnvironmentAnsi);
|
|
if(arPathName==arAlloc)
|
|
GodotHeapFree(pPathNameAnsi);
|
|
if(arProcessorName==arAlloc)
|
|
GodotHeapFree(pPrintProcessorNameAnsi);
|
|
|
|
if(arName == arFailed ||
|
|
arEnvironmentName == arFailed ||
|
|
arPathName == arFailed ||
|
|
arProcessorName == arFailed)
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
|
|
return(RetVal);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=AddPrintProviderW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotAddPrintProvidorW(LPWSTR pName, DWORD level, LPBYTE pProvidorInfo)
|
|
{
|
|
LPSTR pNameAnsi;
|
|
PROVIDOR_INFO_1A pia;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(pName, pNameAnsi);
|
|
GODOT_TO_ACP_STACKALLOC(((PROVIDOR_INFO_1)pProviderInfo)->pName, pia.pName);
|
|
GODOT_TO_ACP_STACKALLOC(((PROVIDOR_INFO_1)pProviderInfo)->pEnvironment, pia.pEnvironment);
|
|
GODOT_TO_ACP_STACKALLOC(((PROVIDOR_INFO_1)pProviderInfo)->pDLLName, pia.pDLLName);
|
|
if((!pNameAnsi && pName) ||
|
|
(!(pia.pName) && ((PROVIDOR_INFO_1)pProviderInfo)->pName) ||
|
|
(!(pia.pEnvironment) && ((PROVIDOR_INFO_1)pProviderInfo)->pEnvironment) ||
|
|
(!(pia.pDLLName) && ((PROVIDOR_INFO_1)pProviderInfo)->pDLLName))
|
|
return(FALSE);
|
|
|
|
return(AddPrintProvidorA(pNameAnsi, level, (LPBYTE)&pia));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=AdvancedDocumentPropertiesW
|
|
Begin=
|
|
LONG __stdcall
|
|
GodotAdvancedDocumentPropertiesW(HWND hWnd, HANDLE hPrinter, LPWSTR pDeviceName,
|
|
PDEVMODEW pDevModeOutput, PDEVMODEW pDevModeInput)
|
|
{
|
|
LONG RetVal;
|
|
LPSTR pDeviceNameAnsi;
|
|
LPDEVMODEA lpdmaOutput;
|
|
LPDEVMODEA lpdmaInput;
|
|
size_t cbInput, cbOutput;
|
|
|
|
if(pDevModeOutput==NULL || pDevModeInput==NULL)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return(0);
|
|
}
|
|
|
|
cbInput = sizeof(DEVMODEA) + (pDevModeInput ? pDevModeInput->dmDriverExtra : 0);
|
|
lpdmaInput = GodotHeapAlloc(cbInput);
|
|
if(lpdmaInput==NULL)
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(0);
|
|
}
|
|
ZeroMemory(lpdmaInput, cbInput);
|
|
DevModeAfromW(lpdmaInput, pDevModeInput);
|
|
|
|
cbOutput = sizeof(DEVMODEA) + (pDevModeOutput ? pDevModeOutput->dmDriverExtra : 0);
|
|
_STACKALLOC(cbOutput, lpdmaOutput);
|
|
if(lpdmaOutput==NULL)
|
|
{
|
|
GodotHeapFree(lpdmaInput);
|
|
return(0);
|
|
}
|
|
ZeroMemory(lpdmaOutput, cbOutput);
|
|
|
|
GODOT_TO_ACP_STACKALLOC(pDeviceName, pDeviceNameAnsi);
|
|
if(pDeviceNameAnsi==NULL && pDeviceName != NULL)
|
|
{
|
|
GodotHeapFree(lpdmaInput);
|
|
return(0);
|
|
}
|
|
|
|
RetVal=AdvancedDocumentPropertiesA(hWnd, hPrinter, pDeviceNameAnsi, lpdmaOutput, lpdmaInput);
|
|
|
|
if(RetVal)
|
|
DevModeWfromA(pDevModeOutput, lpdmaOutput);
|
|
|
|
GodotHeapFree(lpdmaInput);
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=AppendMenuW
|
|
Begin=
|
|
BOOL __stdcall GodotAppendMenuW(HMENU hMenu, UINT uFlags, UINT_PTR uIDNewItem, LPCWSTR lpNewItem)
|
|
{
|
|
|
|
// To detect the string case, we basically need to detect the
|
|
// lack of the ownerdraw/bitmap case (since MF_STRING is
|
|
// actually 0).
|
|
if(!(uFlags & MF_BITMAP || uFlags & MF_OWNERDRAW))
|
|
{
|
|
LPSTR lpNewItemAnsi;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lpNewItem, lpNewItemAnsi);
|
|
|
|
return(AppendMenuA(hMenu, uFlags, uIDNewItem, lpNewItemAnsi));
|
|
}
|
|
|
|
return(AppendMenuA(hMenu, uFlags, uIDNewItem, (LPCSTR)lpNewItem));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=auxGetDevCapsW
|
|
Begin=
|
|
MMRESULT __stdcall GodotauxGetDevCapsW(UINT_PTR uDeviceID, LPAUXCAPSW pac, UINT cbac)
|
|
{
|
|
// UNSUPPORTED FUNCTION: Documented as a failure stub
|
|
|
|
if(cbac < sizeof(AUXCAPSW))
|
|
{
|
|
return(MMSYSERR_INVALPARAM);
|
|
}
|
|
else
|
|
{
|
|
AUXCAPSA acA;
|
|
MMRESULT RetVal;
|
|
|
|
ZeroMemory(&acA, sizeof(AUXCAPSA));
|
|
RetVal = auxGetDevCapsA(uDeviceID, &acA, sizeof(AUXCAPSA));
|
|
|
|
if(RetVal == MMSYSERR_NOERROR)
|
|
{
|
|
pac->wMid = acA.wMid;
|
|
pac->wPid = acA.wPid;
|
|
pac->vDriverVersion = acA.vDriverVersion;
|
|
pac->wTechnology = acA.wTechnology;
|
|
pac->wReserved1 = acA.wReserved1;
|
|
pac->dwSupport = acA.dwSupport;
|
|
MultiByteToWideChar(g_acp, 0, acA.szPname, MAXPNAMELEN, pac->szPname, MAXPNAMELEN);
|
|
}
|
|
return(RetVal);
|
|
}
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=BeginUpdateResourceW
|
|
Begin=
|
|
HANDLE __stdcall GodotBeginUpdateResourceW(LPCWSTR pFileName, BOOL bDeleteExistingResources)
|
|
{
|
|
// UNSUPPORTED FUNCTION: Documented as a failure stub
|
|
return(BeginUpdateResourceInternalW(pFileName, bDeleteExistingResources));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=BroadcastSystemMessageW
|
|
Begin=
|
|
long __stdcall
|
|
GodotBroadcastSystemMessageW(DWORD dwFlags, LPDWORD lpdwRcp, UINT uiMessage, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
// Note that we overloaded a few params here rather than add even
|
|
// more params to GodotTransmitMessage. Slightly hacky but it keeps
|
|
// things central
|
|
return(GodotTransmitMessage(mtBroadcastSystemMessage, 0, uiMessage, wParam,
|
|
lParam, 0, 0, 0, (UINT)dwFlags, 0, lpdwRcp));
|
|
}
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=CallWindowProcA
|
|
Begin=
|
|
LRESULT __stdcall
|
|
GodotCallWindowProcA(WNDPROC lpPrevWndFunc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
return(GodotTransmitMessage(mtCallWindowProcA, hWnd, Msg, wParam, lParam,
|
|
lpPrevWndFunc, 0, 0, 0, 0, 0));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=CallWindowProcW
|
|
Begin=
|
|
LRESULT __stdcall
|
|
GodotCallWindowProcW(WNDPROC lpPrevWndFunc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
return(GodotTransmitMessage(mtCallWindowProc, hWnd, Msg, wParam, lParam,
|
|
lpPrevWndFunc, 0, 0, 0, 0, 0));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=capCreateCaptureWindowW
|
|
Begin=
|
|
HWND __stdcall
|
|
GodotcapCreateCaptureWindowW( LPCWSTR lpszWindowName,
|
|
DWORD dwStyle,
|
|
int x,
|
|
int y,
|
|
int nWidth,
|
|
int nHeight,
|
|
HWND hwndParent,
|
|
int nID
|
|
)
|
|
{
|
|
HWND RetVal;
|
|
LPSTR lpszWindowNameAnsi;
|
|
LPGODOTTLSINFO lpgti = GetThreadInfoSafe(TRUE);
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lpszWindowName, lpszWindowNameAnsi);
|
|
if(!lpgti ||
|
|
(!lpszWindowNameAnsi && lpszWindowName))
|
|
return(0);
|
|
|
|
INIT_WINDOW_SNIFF(lpgti->hHook);
|
|
RetVal=capCreateCaptureWindowA(lpszWindowNameAnsi, dwStyle, x, y, nWidth, nHeight, hwndParent, nID);
|
|
TERM_WINDOW_SNIFF(lpgti->hHook);
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=capGetDriverDescriptionW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotcapGetDriverDescriptionW(UINT wDriverIndex, LPWSTR lpszName, int cbName, LPWSTR lpszVer, int cbVer)
|
|
{
|
|
BOOL RetVal;
|
|
LPSTR lpszNameAnsi;
|
|
LPSTR lpszVerAnsi;
|
|
|
|
_STACKALLOC((cbName*g_mcs)+1, lpszNameAnsi);
|
|
_STACKALLOC((cbVer*g_mcs)+1, lpszVerAnsi);
|
|
if((lpszNameAnsi==NULL) || (lpszVerAnsi==NULL))
|
|
return(FALSE);
|
|
ZeroMemory(lpszNameAnsi, (cbName*g_mcs)+1);
|
|
ZeroMemory(lpszVerAnsi, (cbVer*g_mcs)+1);
|
|
|
|
RetVal=capGetDriverDescriptionA(wDriverIndex, lpszNameAnsi, cbName, lpszVerAnsi, cbVer);
|
|
|
|
if(RetVal)
|
|
{
|
|
MultiByteToWideChar(g_acp, 0, lpszNameAnsi, -1, lpszName, cbName);
|
|
MultiByteToWideChar(g_acp, 0, lpszVerAnsi, -1, lpszVer, cbVer);
|
|
}
|
|
|
|
return(RetVal);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=CharToOemW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotCharToOemW(LPCWSTR lpszSrc, LPSTR lpszDst)
|
|
{
|
|
size_t cchSrc;
|
|
|
|
// MSDN claims this function never returns FALSE. It lies (in the
|
|
// case where the buffers are identical, for example).
|
|
if ((void *)lpszSrc == (void *)lpszDst)
|
|
{
|
|
SetLastError(ERROR_INVALID_ADDRESS);
|
|
return(FALSE);
|
|
}
|
|
|
|
// Why thunk? This function is just a WCHAR->CP_OEM converter, anyway!
|
|
// We should never be longer than the unicode string * g_mcs
|
|
cchSrc = gwcslen(lpszSrc);
|
|
// (Copied the default char choice from oemxlate.c in the Windows depot).
|
|
WideCharToMultiByte(g_oemcp, 0, lpszSrc, cchSrc, lpszDst, cchSrc*g_mcs, "_", NULL);
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=CharToOemBuffW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotCharToOemBuffW(LPCWSTR lpszSrc, LPSTR lpszDst, DWORD cchDstLength)
|
|
{
|
|
LPSTR pTemp;
|
|
|
|
// MSDN claims this function never returns FALSE. It lies (in the
|
|
// case where the buffers are identical, for example).
|
|
if ((void *)lpszSrc == (void *)lpszDst)
|
|
{
|
|
SetLastError(ERROR_INVALID_ADDRESS);
|
|
return(FALSE);
|
|
}
|
|
|
|
// Validate the input and output pointers (taken from the actual API)
|
|
if(IsBadReadPtr(pTemp = (LPSTR)lpszSrc, cchDstLength) ||
|
|
IsBadWritePtr(pTemp = (LPSTR)lpszDst, cchDstLength))
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return(FALSE);
|
|
}
|
|
|
|
// Why thunk? This function is just a WCHAR->CP_OEM converter, anyway!
|
|
// (Copied the default char choice from oemxlate.c in the Windows depot).
|
|
WideCharToMultiByte(g_oemcp, 0, lpszSrc, cchDstLength, lpszDst, cchDstLength*g_mcs, "_", NULL);
|
|
return(TRUE);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=ChangeDisplaySettingsW
|
|
Begin=
|
|
LONG __stdcall
|
|
GodotChangeDisplaySettingsW(LPDEVMODEW lpDevMode, DWORD dwFlags)
|
|
{
|
|
LPDEVMODEA lpdma;
|
|
|
|
_STACKALLOC(sizeof(DEVMODEA) + lpDevMode->dmDriverExtra, lpdma);
|
|
if(lpdma==NULL)
|
|
{
|
|
return(DISP_CHANGE_FAILED);
|
|
}
|
|
ZeroMemory(lpdma, sizeof(DEVMODEA) + lpDevMode->dmDriverExtra);
|
|
if(lpDevMode)
|
|
DevModeAfromW(lpdma, lpDevMode);
|
|
return(ChangeDisplaySettingsA(lpdma, dwFlags));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=ChangeDisplaySettingsExW
|
|
Begin=
|
|
LONG __stdcall
|
|
GodotChangeDisplaySettingsExW( LPCWSTR lpszDeviceName,
|
|
LPDEVMODEW lpDevMode,
|
|
HWND hwnd,
|
|
DWORD dwflags,
|
|
LPVOID lParam
|
|
)
|
|
{
|
|
// Begin locals
|
|
LONG RetVal = DISP_CHANGE_FAILED;
|
|
|
|
if (s_pfnChangeDisplaySettingsExA == NULL)
|
|
{
|
|
// Must allocate stuff for this API call
|
|
s_pfnChangeDisplaySettingsExA = (PFNcdsea)GetUserProc("ChangeDisplaySettingsExA");
|
|
}
|
|
|
|
if (s_pfnChangeDisplaySettingsExA)
|
|
{
|
|
LPSTR lpszDeviceNameAnsi;
|
|
LPDEVMODEA lpdma;
|
|
|
|
_STACKALLOC(sizeof(DEVMODEA) + (lpDevMode ? lpDevMode->dmDriverExtra : 0), lpdma);
|
|
if(lpdma==NULL)
|
|
{
|
|
return(DISP_CHANGE_FAILED);
|
|
}
|
|
|
|
ZeroMemory(lpdma, sizeof(DEVMODEA) + (lpDevMode ? lpDevMode->dmDriverExtra : 0));
|
|
if(lpDevMode)
|
|
DevModeAfromW(lpdma, lpDevMode);
|
|
GODOT_TO_ACP_STACKALLOC(lpszDeviceName, lpszDeviceNameAnsi);
|
|
|
|
RetVal=(s_pfnChangeDisplaySettingsExA(lpszDeviceNameAnsi, lpdma, hwnd, dwflags, lParam));
|
|
}
|
|
else
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=CharLowerW
|
|
Begin=
|
|
LPWSTR __stdcall
|
|
GodotCharLowerW(LPWSTR lpsz)
|
|
{
|
|
if(lpsz)
|
|
{
|
|
if (FSTRING_VALID(lpsz))
|
|
{
|
|
CaseHelper(lpsz, (DWORD)-1, FALSE);
|
|
}
|
|
else
|
|
{
|
|
CaseHelper((LPWSTR)&lpsz, 1, FALSE);
|
|
}
|
|
}
|
|
return lpsz;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=CharLowerBuffW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotCharLowerBuffW(LPWSTR lpsz, DWORD cchLength)
|
|
{
|
|
if (!lpsz || !cchLength)
|
|
return 0;
|
|
|
|
CaseHelper(lpsz, cchLength, FALSE);
|
|
return cchLength;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=CharNextW
|
|
Begin=
|
|
LPWSTR __stdcall
|
|
GodotCharNextW(LPCWSTR lpsz)
|
|
{
|
|
LPWSTR RetVal = (LPWSTR)lpsz;
|
|
|
|
if (lpsz && (L'\0' != *lpsz))
|
|
RetVal++; // this is what _wcsinc does
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=CharPrevW
|
|
Begin=
|
|
LPWSTR __stdcall
|
|
GodotCharPrevW(LPCWSTR lpszStart, LPCWSTR lpszCurrent)
|
|
{
|
|
LPWSTR RetVal = (LPWSTR)lpszCurrent;
|
|
|
|
if (lpszStart && lpszCurrent && (lpszCurrent > lpszStart))
|
|
RetVal--; // this is what _wcsdec does
|
|
else
|
|
RetVal = (LPWSTR)lpszStart;
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=CharUpperW
|
|
Begin=
|
|
LPWSTR __stdcall
|
|
GodotCharUpperW(LPWSTR lpsz)
|
|
{
|
|
if(lpsz)
|
|
{
|
|
if (FSTRING_VALID(lpsz))
|
|
CaseHelper(lpsz, (DWORD)-1, TRUE);
|
|
else
|
|
CaseHelper((LPWSTR)&lpsz, 1, TRUE);
|
|
}
|
|
return lpsz;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=CharUpperBuffW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotCharUpperBuffW(LPWSTR lpsz, DWORD cchLength)
|
|
{
|
|
if (!lpsz || !cchLength)
|
|
return 0;
|
|
|
|
CaseHelper(lpsz, cchLength, TRUE);
|
|
return cchLength;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=ChooseColorW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotChooseColorW(LPCHOOSECOLORW lpcc)
|
|
{
|
|
// Begin locals
|
|
BOOL RetVal;
|
|
CHOOSECOLORA ccAnsi;
|
|
LPGODOTTLSINFO lpgti;
|
|
|
|
// If we cannot get out TLS info, then we cannot proceed
|
|
if(!(lpgti = GetThreadInfoSafe(TRUE)))
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(0);
|
|
}
|
|
|
|
ZeroMemory(&ccAnsi, sizeof(CHOOSECOLORA));
|
|
|
|
// Do the hook
|
|
if((lpgti->pfnChooseColor) && (lpcc->Flags & CC_ENABLEHOOK) && (lpcc->lpfnHook))
|
|
{
|
|
SetLastError(ERROR_INVALID_FILTER_PROC);
|
|
return(0);
|
|
}
|
|
|
|
if ((lpcc->Flags & CC_ENABLEHOOK) && (lpcc->lpfnHook))
|
|
lpgti->pfnChooseColor = lpcc->lpfnHook;
|
|
ccAnsi.lpfnHook = &CCHookProc;
|
|
|
|
ccAnsi.lStructSize = sizeof(CHOOSECOLORA);
|
|
ccAnsi.hwndOwner = lpcc->hwndOwner;
|
|
|
|
if((lpcc->Flags & CC_ENABLETEMPLATEHANDLE) || (lpcc->Flags & CC_ENABLETEMPLATE))
|
|
ccAnsi.hInstance = lpcc->hInstance;
|
|
|
|
ccAnsi.rgbResult = lpcc->rgbResult;
|
|
ccAnsi.lpCustColors = lpcc->lpCustColors; // pointer to an array of 16 COLORREFs
|
|
ccAnsi.Flags = lpcc->Flags;
|
|
ccAnsi.lCustData = lpcc->lCustData;
|
|
|
|
if(lpcc->Flags & CC_ENABLETEMPLATE)
|
|
{
|
|
GODOT_TO_ACP_STACKALLOC(lpcc->lpTemplateName, ccAnsi.lpTemplateName);
|
|
}
|
|
|
|
INIT_WINDOW_SNIFF(lpgti->hHook);
|
|
RetVal=ChooseColorA(&ccAnsi);
|
|
TERM_WINDOW_SNIFF(lpgti->hHook);
|
|
|
|
if ((lpcc->Flags & CC_ENABLEHOOK) && (lpcc->lpfnHook))
|
|
lpgti->pfnChooseColor = NULL;
|
|
|
|
// Begin postcall
|
|
if(RetVal)
|
|
{
|
|
lpcc->rgbResult = ccAnsi.rgbResult;
|
|
lpcc->lpCustColors = ccAnsi.lpCustColors; // pointer to an array of 16 COLORREFs
|
|
lpcc->Flags = ccAnsi.Flags;
|
|
lpcc->lCustData = ccAnsi.lCustData;
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=ChooseFontW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotChooseFontW(LPCHOOSEFONTW lpcf)
|
|
{
|
|
// Begin locals
|
|
BOOL RetVal;
|
|
CHOOSEFONTA cfa;
|
|
LPGODOTTLSINFO lpgti;
|
|
|
|
// If we cannot get out TLS info, then we cannot proceed
|
|
if(!(lpgti = GetThreadInfoSafe(TRUE)))
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(0);
|
|
}
|
|
|
|
ZeroMemory(&cfa, sizeof(CHOOSEFONTA));
|
|
|
|
// Do the hook
|
|
if((lpgti->pfnChooseFont) && (lpcf->Flags & CF_ENABLEHOOK) && (lpcf->lpfnHook))
|
|
{
|
|
SetLastError(ERROR_INVALID_FILTER_PROC);
|
|
return(0);
|
|
}
|
|
|
|
if ((lpcf->Flags & CF_ENABLEHOOK) && (lpcf->lpfnHook))
|
|
lpgti->pfnChooseFont = lpcf->lpfnHook;
|
|
cfa.lpfnHook = &CFHookProc;
|
|
|
|
cfa.lStructSize = sizeof(CHOOSEFONTA);
|
|
cfa.hwndOwner = lpcf->hwndOwner;
|
|
|
|
if((lpcf->Flags & CF_PRINTERFONTS) || (lpcf->Flags & CF_BOTH))
|
|
cfa.hDC = lpcf->hDC;
|
|
|
|
_STACKALLOC(sizeof(LOGFONTA), cfa.lpLogFont);
|
|
ZeroMemory(cfa.lpLogFont, sizeof(LOGFONTA));
|
|
LogFontAfromW(cfa.lpLogFont, lpcf->lpLogFont);
|
|
cfa.iPointSize = lpcf->iPointSize;
|
|
cfa.Flags = lpcf->Flags;
|
|
cfa.rgbColors = lpcf->rgbColors;
|
|
cfa.lCustData = lpcf->lCustData;
|
|
|
|
if(lpcf->Flags & CF_ENABLETEMPLATE)
|
|
{
|
|
GODOT_TO_ACP_STACKALLOC(lpcf->lpTemplateName, cfa.lpTemplateName);
|
|
}
|
|
|
|
//if((lpcf->Flags & CF_ENABLETEMPLATEHANDLE) || (lpcf->Flags & CF_ENABLETEMPLATE))
|
|
cfa.hInstance = lpcf->hInstance;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lpcf->lpszStyle, cfa.lpszStyle);
|
|
cfa.nFontType = lpcf->nFontType;
|
|
cfa.nSizeMin = lpcf->nSizeMin;
|
|
cfa.nSizeMax = lpcf->nSizeMax;
|
|
|
|
INIT_WINDOW_SNIFF(lpgti->hHook);
|
|
RetVal=ChooseFontA(&cfa);
|
|
TERM_WINDOW_SNIFF(lpgti->hHook);
|
|
|
|
if ((lpcf->Flags & CF_ENABLEHOOK) && (lpcf->lpfnHook))
|
|
lpgti->pfnChooseFont = NULL;
|
|
|
|
// Begin postcall
|
|
if(RetVal)
|
|
{
|
|
size_t cbStyle;
|
|
|
|
lpcf->hDC = cfa.hDC;
|
|
LogFontWfromA(lpcf->lpLogFont, cfa.lpLogFont);
|
|
lpcf->iPointSize = cfa.iPointSize;
|
|
lpcf->Flags = cfa.Flags;
|
|
lpcf->rgbColors = cfa.rgbColors;
|
|
lpcf->lCustData = cfa.lCustData;
|
|
cbStyle = (lpcf->lpszStyle==NULL ? 0 : lstrlenA( cfa.lpszStyle));
|
|
if(FSTRING_VALID(cfa.lpszStyle) && FSTRING_VALID(lpcf->lpszStyle) && (cbStyle > 0))
|
|
MultiByteToWideChar(g_acp, 0, cfa.lpszStyle, -1, lpcf->lpszStyle, cbStyle);
|
|
lpcf->nFontType = cfa.nFontType;
|
|
lpcf->nSizeMin = cfa.nSizeMin;
|
|
lpcf->nSizeMax = cfa.nSizeMax;
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=CompareStringW
|
|
Begin=
|
|
int __stdcall
|
|
GodotCompareStringW( LCID Locale,
|
|
DWORD dwCmpFlags,
|
|
LPCWSTR lpString1,
|
|
int cchCount1,
|
|
LPCWSTR lpString2,
|
|
int cchCount2
|
|
)
|
|
{
|
|
// Begin locals
|
|
int RetVal;
|
|
LPSTR lpString1A, lpString2A;
|
|
size_t cchString1, cchString2;
|
|
UINT cpg;
|
|
UINT mcs;
|
|
|
|
cpg = CpgFromLocale(Locale);
|
|
mcs = CbPerChOfCpg(cpg);
|
|
|
|
// Begin precall
|
|
if (FSTRING_VALID(lpString1))
|
|
{
|
|
if(cchCount1==-1)
|
|
cchString1 = gwcslen(lpString1) + 1;
|
|
else
|
|
cchString1 = cchCount1 + 1;
|
|
_STACKALLOC(cchString1*mcs, lpString1A);
|
|
if(!lpString1A)
|
|
{
|
|
return(FALSE);
|
|
}
|
|
WideCharToMultiByte(cpg, 0, lpString1, cchString1, lpString1A, cchString1*mcs, NULL, NULL);
|
|
}
|
|
else
|
|
lpString1A = (LPSTR)lpString1;
|
|
|
|
if (FSTRING_VALID(lpString2))
|
|
{
|
|
if(cchCount2==-1)
|
|
cchString2 = gwcslen(lpString2) + 1;
|
|
else
|
|
cchString2 = cchCount2 + 1;
|
|
_STACKALLOC(cchString2*mcs, lpString2A);
|
|
if(!lpString2A)
|
|
{
|
|
return(FALSE);
|
|
}
|
|
WideCharToMultiByte(cpg, 0, lpString2, cchString2, lpString2A, cchString2*mcs, NULL, NULL);
|
|
}
|
|
else
|
|
lpString2A = (LPSTR)lpString2;
|
|
|
|
RetVal=CompareStringA(Locale, dwCmpFlags, lpString1A, cchCount1, lpString2A, cchCount2);
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=ConfigurePortW
|
|
Begin=
|
|
BOOL __stdcall GodotConfigurePortW(LPWSTR pName, HWND hWnd, LPWSTR pPortName)
|
|
{
|
|
BOOL RetVal = FALSE;
|
|
LPSTR pNameAnsi = NULL;
|
|
LPSTR pPortNameAnsi = NULL;
|
|
ALLOCRETURN arName = GodotToAcpOnHeap(pName, &pNameAnsi);
|
|
ALLOCRETURN arPortName = GodotToAcpOnHeap(pPortName, &pPortNameAnsi);
|
|
|
|
if(arName != arFailed && arPortName != arFailed)
|
|
RetVal = ConfigurePortA(pNameAnsi, hWnd, pPortNameAnsi);
|
|
|
|
if(arName==arAlloc)
|
|
GodotHeapFree(pNameAnsi);
|
|
if(arPortName==arAlloc)
|
|
GodotHeapFree(pPortNameAnsi);
|
|
|
|
if(arName == arFailed || arPortName == arFailed)
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(RetVal);
|
|
}
|
|
|
|
End=
|
|
|
|
|
|
[EFunc]
|
|
TemplateName=CopyFileW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotCopyFileW(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName, BOOL bFailIfExists)
|
|
{
|
|
LPSTR lpExistingFileNameA, lpNewFileNameA;
|
|
UINT cpg = FILES_CPG;
|
|
|
|
// Begin precall
|
|
GODOT_TO_CPG_STACKALLOC(lpExistingFileName, lpExistingFileNameA, cpg, g_mcs);
|
|
GODOT_TO_CPG_STACKALLOC(lpNewFileName, lpNewFileNameA, cpg, g_mcs);
|
|
|
|
return(CopyFileA(lpExistingFileNameA, lpNewFileNameA, bFailIfExists));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=CopyFileExW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotCopyFileExW( LPCWSTR lpExisting,
|
|
LPCWSTR lpNew,
|
|
LPPROGRESS_ROUTINE lpProgress,
|
|
LPVOID lpData,
|
|
LPBOOL pbCancel,
|
|
DWORD dwCopyFlags
|
|
)
|
|
{
|
|
// Begin locals
|
|
LPSTR lpEfnA, lpNfnA;
|
|
UINT cpg = FILES_CPG;
|
|
|
|
if (s_pfnCopyFileExA == NULL)
|
|
{
|
|
// Must allocate stuff for this API call
|
|
s_pfnCopyFileExA = (PFNcfea)GetKernelProc("CopyFileExA");
|
|
}
|
|
|
|
if (s_pfnCopyFileExA)
|
|
{
|
|
GODOT_TO_CPG_STACKALLOC(lpExisting, lpEfnA, cpg, g_mcs);
|
|
GODOT_TO_CPG_STACKALLOC(lpNew, lpNfnA, cpg, g_mcs);
|
|
|
|
return((s_pfnCopyFileExA(lpEfnA, lpNfnA, lpProgress, lpData, pbCancel, dwCopyFlags)));
|
|
|
|
}
|
|
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
return FALSE;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=CreateColorSpaceW
|
|
Begin=
|
|
HCOLORSPACE __stdcall
|
|
GodotCreateColorSpaceW(LPLOGCOLORSPACEW plcs)
|
|
{
|
|
LOGCOLORSPACEA lcsa;
|
|
|
|
// Begin precall
|
|
ZeroMemory(&lcsa, sizeof(LOGCOLORSPACEA));
|
|
memcpy(&lcsa, plcs, 6*sizeof(DWORD)+sizeof(LCSCSTYPE)+sizeof(LCSGAMUTMATCH)+sizeof(CIEXYZTRIPLE));
|
|
lcsa.lcsSize = sizeof(LOGCOLORSPACEA);
|
|
WideCharToMultiByte(g_acp, 0,
|
|
plcs->lcsFilename, MAX_PATH,
|
|
lcsa.lcsFilename, MAX_PATH,
|
|
NULL, NULL);
|
|
|
|
return(CreateColorSpaceA(&lcsa));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=CreateDCW
|
|
Begin=
|
|
HDC __stdcall
|
|
GodotCreateDCW(LPCWSTR lpszDriver, LPCWSTR lpszDevice, LPCWSTR lpszOutput, DEVMODEW * lpInitData)
|
|
{
|
|
LPSTR lpszDriverAnsi, lpszDeviceAnsi, lpszOutputAnsi;
|
|
LPDEVMODEA lpdma;
|
|
|
|
// Begin precall
|
|
GODOT_TO_ACP_STACKALLOC(lpszDriver, lpszDriverAnsi);
|
|
GODOT_TO_ACP_STACKALLOC(lpszDevice, lpszDeviceAnsi);
|
|
GODOT_TO_ACP_STACKALLOC(lpszOutput, lpszOutputAnsi);
|
|
if((!lpszDriverAnsi && lpszDriver) ||
|
|
(!lpszDeviceAnsi && lpszDevice) ||
|
|
(!lpszOutputAnsi && lpszOutput))
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
if (lpInitData)
|
|
{
|
|
_STACKALLOC(sizeof(DEVMODEA) + lpInitData->dmDriverExtra, lpdma);
|
|
if(lpdma==NULL)
|
|
{
|
|
return(0);
|
|
}
|
|
ZeroMemory(lpdma, sizeof(DEVMODEA) + lpInitData->dmDriverExtra);
|
|
DevModeAfromW(lpdma, lpInitData);
|
|
return(CreateDCA(lpszDriverAnsi, lpszDeviceAnsi, lpszOutputAnsi, lpdma));
|
|
}
|
|
else
|
|
return(CreateDCA(lpszDriverAnsi, lpszDeviceAnsi, lpszOutputAnsi, NULL));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=CreateDialogIndirectParamW
|
|
Begin=
|
|
HWND __stdcall
|
|
GodotCreateDialogIndirectParamW( HINSTANCE hInst,
|
|
LPCDLGTEMPLATEW lpTemplate,
|
|
HWND hWnd,
|
|
DLGPROC lpfn,
|
|
LPARAM dwParam
|
|
)
|
|
{
|
|
LPGODOTTLSINFO lpgti = GetThreadInfoSafe(TRUE);
|
|
HWND RetVal;
|
|
|
|
if(!lpgti)
|
|
{
|
|
RetVal = 0;
|
|
}
|
|
else
|
|
{
|
|
lpgti->pfnDlgProc = lpfn;
|
|
INIT_WINDOW_SNIFF(lpgti->hHook);
|
|
RetVal = CreateDialogIndirectParamA(hInst, lpTemplate, hWnd, &DialogProc, dwParam);
|
|
TERM_WINDOW_SNIFF(lpgti->hHook);
|
|
}
|
|
return(RetVal);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=CreateDialogParamW
|
|
Begin=
|
|
HWND __stdcall
|
|
GodotCreateDialogParamW(HINSTANCE hInst, LPCWSTR lpTemplate, HWND hWnd, DLGPROC lpfn, LPARAM dwParam)
|
|
{
|
|
LPGODOTTLSINFO lpgti = GetThreadInfoSafe(TRUE);
|
|
|
|
if(!lpgti)
|
|
{
|
|
return(0);
|
|
}
|
|
else
|
|
{
|
|
LPSTR lpTemplateAnsi;
|
|
HWND RetVal;
|
|
|
|
lpgti->pfnDlgProc = lpfn;
|
|
GODOT_TO_ACP_STACKALLOC(lpTemplate, lpTemplateAnsi);
|
|
if(!lpTemplateAnsi && lpTemplate)
|
|
return(0);
|
|
INIT_WINDOW_SNIFF(lpgti->hHook);
|
|
RetVal = CreateDialogParamA(hInst, lpTemplateAnsi, hWnd, &DialogProc, dwParam);
|
|
TERM_WINDOW_SNIFF(lpgti->hHook);
|
|
return(RetVal);
|
|
}
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=CreateDirectoryW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotCreateDirectoryW(LPCWSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
|
|
{
|
|
// Begin locals
|
|
LPSTR lpPathNameAnsi;
|
|
|
|
// Begin precall
|
|
GODOT_TO_CPG_STACKALLOC(lpPathName, lpPathNameAnsi, FILES_CPG, g_mcs);
|
|
|
|
return(CreateDirectoryA(lpPathNameAnsi, lpSecurityAttributes));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=CreateDirectoryExW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotCreateDirectoryExW(LPCWSTR lpTemplate, LPCWSTR lpNew, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
|
|
{
|
|
// Begin locals
|
|
LPSTR lpTemplateAnsi, lpNewAnsi;
|
|
UINT cpg = FILES_CPG;
|
|
|
|
// Begin precall
|
|
GODOT_TO_CPG_STACKALLOC(lpTemplate, lpTemplateAnsi, cpg, g_mcs);
|
|
GODOT_TO_CPG_STACKALLOC(lpNew, lpNewAnsi, cpg, g_mcs);
|
|
|
|
return(CreateDirectoryExA(lpTemplateAnsi, lpNewAnsi, lpSecurityAttributes));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=CreateFileW
|
|
Begin=
|
|
HANDLE __stdcall
|
|
GodotCreateFileW( LPCWSTR lpFileName,
|
|
DWORD dwDesiredAccess,
|
|
DWORD dwShareMode,
|
|
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
|
|
DWORD dwCreationDisposition,
|
|
DWORD dwFlagsAndAttributes,
|
|
HANDLE hTemplateFile
|
|
)
|
|
{
|
|
LPSTR lpFileNameAnsi;
|
|
|
|
// Begin precall
|
|
GODOT_TO_CPG_STACKALLOC(lpFileName, lpFileNameAnsi, FILES_CPG, g_mcs);
|
|
|
|
return(CreateFileA(lpFileNameAnsi,
|
|
dwDesiredAccess,
|
|
dwShareMode,
|
|
lpSecurityAttributes,
|
|
dwCreationDisposition,
|
|
dwFlagsAndAttributes,
|
|
hTemplateFile
|
|
));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=CreateFontIndirectW
|
|
Begin=
|
|
HFONT __stdcall
|
|
GodotCreateFontIndirectW(LOGFONTW * lplf
|
|
)
|
|
{
|
|
LOGFONTA lfa;
|
|
|
|
ZeroMemory(&lfa, sizeof(LOGFONTA));
|
|
LogFontAfromW(&lfa, lplf);
|
|
|
|
return(CreateFontIndirectA(&lfa));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=CreateICW
|
|
Begin=
|
|
HDC __stdcall
|
|
GodotCreateICW( LPCWSTR lpszDriver,
|
|
LPCWSTR lpszDevice,
|
|
LPCWSTR lpszOutput,
|
|
DEVMODEW * lpdvmInit
|
|
)
|
|
{
|
|
LPSTR lpszDriverAnsi, lpszDeviceAnsi;
|
|
LPDEVMODEA lpdma;
|
|
|
|
// Begin precall
|
|
GODOT_TO_ACP_STACKALLOC(lpszDriver, lpszDriverAnsi);
|
|
GODOT_TO_ACP_STACKALLOC(lpszDevice, lpszDeviceAnsi);
|
|
if((!lpszDriverAnsi && lpszDriver) ||
|
|
(!lpszDeviceAnsi && lpszDevice))
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
if(lpdvmInit)
|
|
{
|
|
_STACKALLOC(sizeof(DEVMODEA) + lpdvmInit->dmDriverExtra, lpdma);
|
|
if(lpdma==NULL)
|
|
{
|
|
return(0);
|
|
}
|
|
ZeroMemory(lpdma, sizeof(DEVMODEA) + lpdvmInit->dmDriverExtra);
|
|
DevModeAfromW(lpdma, lpdvmInit);
|
|
|
|
return(CreateICA(lpszDriverAnsi, lpszDeviceAnsi, NULL, lpdma));
|
|
}
|
|
else
|
|
return(CreateICA(lpszDriverAnsi, lpszDeviceAnsi, NULL, NULL));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=CreateMDIWindowW
|
|
Begin=
|
|
HWND __stdcall
|
|
GodotCreateMDIWindowW( LPCWSTR lpClassName,
|
|
LPCWSTR lpWindowName,
|
|
DWORD dwStyle,
|
|
int X,
|
|
int Y,
|
|
int nWidth,
|
|
int nHeight,
|
|
HWND hWndParent,
|
|
HINSTANCE hInstance,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
HWND RetVal;
|
|
LPSTR lpClassNameAnsi, lpWindowNameAnsi;
|
|
LPGODOTTLSINFO lpgti = GetThreadInfoSafe(TRUE);
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lpClassName, lpClassNameAnsi);
|
|
GODOT_TO_ACP_STACKALLOC(lpWindowName, lpWindowNameAnsi);
|
|
if(!lpgti ||
|
|
(lpClassName && !lpClassNameAnsi) ||
|
|
(lpWindowName && !lpWindowNameAnsi))
|
|
return(0);
|
|
|
|
INIT_WINDOW_SNIFF(lpgti->hHook);
|
|
RetVal=CreateMDIWindowA(lpClassNameAnsi, lpWindowNameAnsi, dwStyle, X, Y,
|
|
nWidth, nHeight, hWndParent, hInstance, lParam);
|
|
TERM_WINDOW_SNIFF(lpgti->hHook);
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=CreateProcessW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotCreateProcessW( LPCWSTR lpApplicationName,
|
|
LPWSTR lpCommandLine,
|
|
LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
|
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
|
BOOL bInheritHandles,
|
|
DWORD dwCreationFlags,
|
|
LPVOID lpEnvironment,
|
|
LPCWSTR lpCurrentDirectory,
|
|
LPSTARTUPINFOW lpsiw,
|
|
LPPROCESS_INFORMATION lpProcessInformation
|
|
)
|
|
{
|
|
LPSTR lpApplicationNameAnsi, lpCommandLineAnsi, lpCurrentDirectoryAnsi;
|
|
STARTUPINFOA sia;
|
|
|
|
// Begin precall
|
|
ZeroMemory(&sia, sizeof(STARTUPINFOA));
|
|
GODOT_TO_ACP_STACKALLOC(lpApplicationName, lpApplicationNameAnsi);
|
|
GODOT_TO_ACP_STACKALLOC(lpCommandLine, lpCommandLineAnsi);
|
|
GODOT_TO_ACP_STACKALLOC(lpCurrentDirectory, lpCurrentDirectoryAnsi);
|
|
sia.cb = sizeof(STARTUPINFOA);
|
|
GODOT_TO_ACP_STACKALLOC(lpsiw->lpReserved, sia.lpReserved);
|
|
GODOT_TO_ACP_STACKALLOC(lpsiw->lpDesktop, sia.lpDesktop);
|
|
GODOT_TO_ACP_STACKALLOC(lpsiw->lpTitle, sia.lpTitle);
|
|
sia.dwX = lpsiw->dwX;
|
|
sia.dwY = lpsiw->dwY;
|
|
sia.dwXSize = lpsiw->dwXSize;
|
|
sia.dwYSize = lpsiw->dwYSize;
|
|
sia.dwXCountChars = lpsiw->dwXCountChars;
|
|
sia.dwYCountChars = lpsiw->dwYCountChars;
|
|
sia.dwFillAttribute = lpsiw->dwFillAttribute;
|
|
sia.dwFlags = lpsiw->dwFlags;
|
|
sia.wShowWindow = lpsiw->wShowWindow;
|
|
sia.cbReserved2 = lpsiw->cbReserved2;
|
|
sia.lpReserved2 = lpsiw->lpReserved2;
|
|
sia.hStdInput = lpsiw->hStdInput;
|
|
sia.hStdOutput = lpsiw->hStdOutput;
|
|
sia.hStdError = lpsiw->hStdError;
|
|
|
|
return(CreateProcessA(lpApplicationNameAnsi,
|
|
lpCommandLineAnsi,
|
|
lpProcessAttributes,
|
|
lpThreadAttributes,
|
|
bInheritHandles,
|
|
dwCreationFlags,
|
|
lpEnvironment,
|
|
lpCurrentDirectoryAnsi,
|
|
&sia,
|
|
lpProcessInformation
|
|
));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=CreateStdAccessibleProxyW
|
|
Begin=
|
|
HRESULT __stdcall
|
|
GodotCreateStdAccessibleProxyW(HWND hwnd, LPCWSTR pClassName, LONG idObject, const IID * riid, void ** ppv)
|
|
{
|
|
HRESULT RetVal = E_NOTIMPL;
|
|
|
|
if (s_pfnCreateStdAccessibleProxy == NULL)
|
|
{
|
|
// Must allocate stuff for this API call
|
|
s_pfnCreateStdAccessibleProxy = (PFNcsapa)GetOleAccProc("CreateStdAccessibleProxyA");
|
|
}
|
|
|
|
if (s_pfnCreateStdAccessibleProxy)
|
|
{
|
|
LPSTR pClassNameAnsi;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(pClassName, pClassNameAnsi);
|
|
if(!pClassNameAnsi && pClassName)
|
|
return(E_FAIL);
|
|
|
|
RetVal = (s_pfnCreateStdAccessibleProxy(hwnd, pClassNameAnsi, idObject, riid, ppv));
|
|
|
|
}
|
|
else
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=CreateWindowExW
|
|
Begin=
|
|
HWND __stdcall
|
|
GodotCreateWindowExW( DWORD dwExStyle,
|
|
LPCWSTR lpClassName,
|
|
LPCWSTR lpWindowName,
|
|
DWORD dwStyle,
|
|
int X,
|
|
int Y,
|
|
int nWidth,
|
|
int nHeight,
|
|
HWND hWndParent,
|
|
HMENU hMenu,
|
|
HINSTANCE hInstance,
|
|
LPVOID lpParam
|
|
)
|
|
{
|
|
// Begin locals
|
|
HWND RetVal;
|
|
LPSTR lpClassNameAnsi = NULL;
|
|
LPSTR lpWindowNameAnsi = NULL;
|
|
LPGODOTTLSINFO lpgti = GetThreadInfoSafe(TRUE);
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lpClassName, lpClassNameAnsi);
|
|
GODOT_TO_ACP_STACKALLOC(lpWindowName, lpWindowNameAnsi);
|
|
if(!lpgti ||
|
|
(!lpClassNameAnsi && lpClassName) ||
|
|
(!lpWindowNameAnsi && lpWindowName))
|
|
return(0);
|
|
|
|
INIT_WINDOW_SNIFF(lpgti->hHook);
|
|
RetVal=CreateWindowExA(dwExStyle,
|
|
lpClassNameAnsi,
|
|
lpWindowNameAnsi,
|
|
dwStyle,
|
|
X,
|
|
Y,
|
|
nWidth,
|
|
nHeight,
|
|
hWndParent,
|
|
hMenu,
|
|
hInstance,
|
|
lpParam
|
|
);
|
|
TERM_WINDOW_SNIFF(lpgti->hHook);
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=CreateWaitableTimerW
|
|
Begin=
|
|
HANDLE __stdcall
|
|
GodotCreateWaitableTimerW(LPSECURITY_ATTRIBUTES lpTimerAttributes, BOOL bManualReset, LPCWSTR lpTimerName)
|
|
{
|
|
// Begin locals
|
|
HANDLE RetVal = NULL;
|
|
|
|
if (s_pfnCreateWaitableTimerA == NULL)
|
|
{
|
|
// Must allocate stuff for this API call
|
|
s_pfnCreateWaitableTimerA = (PFNcwta)GetKernelProc("CreateWaitableTimerA");
|
|
}
|
|
|
|
if (s_pfnCreateWaitableTimerA)
|
|
{
|
|
LPSTR lpTimerNameAnsi;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lpTimerName, lpTimerNameAnsi);
|
|
|
|
RetVal = (s_pfnCreateWaitableTimerA(lpTimerAttributes, bManualReset, lpTimerNameAnsi));
|
|
|
|
}
|
|
else
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=DdeConnect
|
|
Begin=
|
|
HCONV __stdcall
|
|
GodotDdeConnect(DWORD idInst, HSZ hszService, HSZ hszTopic, PCONVCONTEXT pCC)
|
|
{
|
|
if(pCC)
|
|
{
|
|
// CP_WINUNICODE is not a valid param for Win95/98/ME, so
|
|
// we will munge it here it it exists. Nothing else needs to
|
|
// change
|
|
if(pCC->iCodePage == CP_WINUNICODE)
|
|
pCC->iCodePage = CP_WINANSI;
|
|
}
|
|
|
|
return(DdeConnect(idInst, hszService, hszTopic, pCC));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=DdeConnectList
|
|
Begin=
|
|
HCONVLIST __stdcall
|
|
GodotDdeConnectList(DWORD idInst, HSZ hszService, HSZ hszTopic, HCONVLIST hConvList, PCONVCONTEXT pCC)
|
|
{
|
|
if(pCC)
|
|
{
|
|
// CP_WINUNICODE is not a valid param for Win95/98/ME, so
|
|
// we will munge it here it it exists. Nothing else needs to
|
|
// change
|
|
if(pCC->iCodePage == CP_WINUNICODE)
|
|
pCC->iCodePage = CP_WINANSI;
|
|
}
|
|
|
|
return(DdeConnectList(idInst, hszService, hszTopic, hConvList, pCC));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=DdeCreateStringHandleW
|
|
Begin=
|
|
HSZ __stdcall
|
|
GodotDdeCreateStringHandleW(DWORD idInst, LPCWSTR psz, int iCodePage)
|
|
{
|
|
// Begin locals
|
|
HSZ RetVal;
|
|
LPSTR pszAnsi;
|
|
|
|
if(iCodePage == CP_WINUNICODE)
|
|
{
|
|
GODOT_TO_ACP_STACKALLOC(psz, pszAnsi);
|
|
if(pszAnsi==NULL)
|
|
{
|
|
RetVal = 0L;
|
|
}
|
|
|
|
RetVal=DdeCreateStringHandleA(idInst, pszAnsi, iCodePage);
|
|
}
|
|
else if((iCodePage == CP_WINANSI) || // This is what the docs say it must be
|
|
(iCodePage == (int)GetACP()) || // Turns out it can be this,
|
|
(iCodePage == (int)GetOEMCP())) // and it can also be this
|
|
{
|
|
// No conversion needed
|
|
RetVal=DdeCreateStringHandleA(idInst, (LPSTR)psz, iCodePage);
|
|
}
|
|
else
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
RetVal = 0L;
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=DdeInitializeW
|
|
Begin=
|
|
UINT __stdcall
|
|
GodotDdeInitializeW(LPDWORD pidInst, PFNCALLBACK pfnCallback, DWORD afCmd, DWORD ulRes)
|
|
{
|
|
// CONSIDER: Several DDE messages might not have the right iCodePage flag in them:
|
|
// XTYP_CONNECT - CONVCONTEXT in dwData1
|
|
// XTYP_WILDCONNECT - CONVCONTEXT in dwData1
|
|
// XTYP_MONITOR - several potential structures that do this
|
|
return(DdeInitializeA(pidInst, pfnCallback, afCmd, ulRes));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=DdeQueryConvInfo
|
|
Begin=
|
|
UINT __stdcall
|
|
GodotDdeQueryConvInfo(HCONV hConv, DWORD idTransaction, PCONVINFO pConvInfo)
|
|
{
|
|
UINT RetVal;
|
|
BOOL fUnicode = FALSE;
|
|
|
|
// Munge the structure if it is there to fix up CP_WINUNICODE refs
|
|
if(pConvInfo)
|
|
{
|
|
if(pConvInfo->ConvCtxt.iCodePage == CP_WINUNICODE)
|
|
{
|
|
fUnicode = TRUE;
|
|
pConvInfo->ConvCtxt.iCodePage = CP_WINANSI;
|
|
}
|
|
}
|
|
|
|
// Call the API
|
|
RetVal=DdeQueryConvInfo(hConv, idTransaction, pConvInfo);
|
|
|
|
// Fix the structure back if we mucked with it
|
|
if(fUnicode)
|
|
pConvInfo->ConvCtxt.iCodePage = CP_WINUNICODE;
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=DdeQueryStringW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotDdeQueryStringW(DWORD idInst, HSZ hsz, LPWSTR psz, DWORD cchMax, int iCodePage)
|
|
{
|
|
// Begin locals
|
|
DWORD RetVal;
|
|
LPSTR pszAnsi;
|
|
|
|
if(iCodePage == CP_WINUNICODE)
|
|
{
|
|
if(psz)
|
|
{
|
|
_STACKALLOC(cchMax*g_mcs, pszAnsi);
|
|
}
|
|
else
|
|
pszAnsi = NULL;
|
|
RetVal=DdeQueryStringA(idInst, hsz, pszAnsi, cchMax, CP_WINANSI);
|
|
|
|
if(psz && pszAnsi)
|
|
{
|
|
MultiByteToWideChar(g_acp, 0, pszAnsi, cchMax*g_mcs, psz, cchMax);
|
|
RetVal = gwcslen(psz);
|
|
}
|
|
else
|
|
{
|
|
// We have been given a return that the PSDK claims is ANSI TCHARs. This
|
|
// count should match the Unicode cch so we can leave it alone.
|
|
}
|
|
}
|
|
else if((iCodePage == CP_WINANSI) || // This is what the docs say it must be
|
|
(iCodePage == (int)GetACP()) || // Turns out it can be this,
|
|
(iCodePage == (int)GetOEMCP())) // and it can also be this
|
|
{
|
|
// Not doing a Unicode code page, so no conversion needed or wanted
|
|
RetVal=DdeQueryStringA(idInst, hsz, (LPSTR)psz, cchMax, iCodePage);
|
|
}
|
|
else
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
RetVal = 0L;
|
|
}
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=DefDlgProcW
|
|
Begin=
|
|
LRESULT __stdcall
|
|
GodotDefDlgProcW(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
return(GodotTransmitMessage(mtDefDlgProc, hDlg, Msg, wParam, lParam, 0, 0, 0, 0, 0, 0));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=DefFrameProcW
|
|
Begin=
|
|
LRESULT __stdcall
|
|
GodotDefFrameProcW(HWND hWnd, HWND hWndMDIClient, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
// Overloading GTM's dwData param for hWndMDIClient
|
|
return(GodotTransmitMessage(mtDefFrameProc, hWnd, uMsg, wParam,
|
|
lParam, 0, 0, (DWORD)hWndMDIClient, 0, 0, 0));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=DefMDIChildProcW
|
|
Begin=
|
|
LRESULT __stdcall
|
|
GodotDefMDIChildProcW(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
return(GodotTransmitMessage(mtDefMDIChildProc, hWnd, uMsg, wParam, lParam, 0, 0, 0, 0, 0, 0));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=DefWindowProcW
|
|
Begin=
|
|
LRESULT __stdcall
|
|
GodotDefWindowProcW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
return(GodotTransmitMessage(mtDefWindowProc, hWnd, Msg, wParam, lParam, 0, 0, 0, 0, 0, 0));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=DeleteFileW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotDeleteFileW(LPCWSTR lpFileName)
|
|
{
|
|
LPSTR lpFileNameAnsi;
|
|
|
|
GODOT_TO_CPG_STACKALLOC(lpFileName, lpFileNameAnsi, FILES_CPG, g_mcs);
|
|
|
|
return(DeleteFileA(lpFileNameAnsi));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=DeleteMinitorW
|
|
Begin=
|
|
BOOL __stdcall GodotDeleteMonitorW(LPWSTR pName, LPWSTR pEnvironment, LPWSTR pMonitorName)
|
|
{
|
|
BOOL RetVal = FALSE;
|
|
LPSTR pNameAnsi = NULL;
|
|
LPSTR pEnvironmentAnsi = NULL;
|
|
LPSTR pMonitorNameAnsi = NULL;
|
|
ALLOCRETURN arName = GodotToAcpOnHeap(pName, &pNameAnsi);
|
|
ALLOCRETURN arEnvironmentName = GodotToAcpOnHeap(pEnvironment, &pEnvironmentAnsi);
|
|
ALLOCRETURN arMonitorName = GodotToAcpOnHeap(pMonitorName, &pMonitorNameAnsi);
|
|
|
|
if(arName != arFailed && arEnvironmentName != arFailed && arMonitorName != arFailed)
|
|
RetVal=DeleteMonitorWA(pNameAnsi, pEnvironmentAnsi, pMonitorNameAnsi);
|
|
|
|
if(arName==arAlloc)
|
|
GodotHeapFree(pNameAnsi);
|
|
if(arEnvironmentName==arAlloc)
|
|
GodotHeapFree(pEnvironmentAnsi);
|
|
if(arMonitorName==arAlloc)
|
|
GodotHeapFree(pMonitorNameAnsi);
|
|
|
|
if(arName == arFailed || arEnvironmentName == arFailed || arMonitorName == arFailed)
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=DeletePortW
|
|
Begin=
|
|
BOOL __stdcall GodotDeletePortW(LPWSTR pName, HWND hWnd, LPWSTR pPortName)
|
|
{
|
|
BOOL RetVal = FALSE;
|
|
LPSTR pNameAnsi = NULL;
|
|
LPSTR pPortNameAnsi = NULL;
|
|
ALLOCRETURN arName = GodotToAcpOnHeap(pName, &pNameAnsi);
|
|
ALLOCRETURN arPortName = GodotToAcpOnHeap(pPortName, &pPortNameAnsi);
|
|
|
|
if(arName != arFailed && arPortName != arFailed)
|
|
RetVal = DeletePortA(pNameAnsi, hWnd, pPortNameAnsi);
|
|
|
|
if(arName==arAlloc)
|
|
GodotHeapFree(pNameAnsi);
|
|
if(arPortName==arAlloc)
|
|
GodotHeapFree(pPortNameAnsi);
|
|
|
|
if(arName == arFailed || arPortName == arFailed)
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(RetVal);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=DeletePrinterDriverW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotDeletePrinterDriverW(LPWSTR pName, LPWSTR pEnvironment, LPWSTR pDriverName)
|
|
{
|
|
BOOL RetVal = FALSE;
|
|
LPSTR pNameAnsi = NULL;
|
|
LPSTR pEnvironmentAnsi = NULL;
|
|
LPSTR pDriverNameAnsi = NULL;
|
|
ALLOCRETURN arName = GodotToAcpOnHeap(pName, &pNameAnsi);
|
|
ALLOCRETURN arEnvironmentName = GodotToAcpOnHeap(pEnvironment, &pEnvironmentAnsi);
|
|
ALLOCRETURN arDriverName = GodotToAcpOnHeap(pDriverName, &pDriverNameAnsi);
|
|
|
|
if(arName != arFailed && arEnvironmentName != arFailed && arDriverName != arFailed)
|
|
RetVal = DeletePrinterDriverA(pNameAnsi, pEnvironmentAnsi, pDriverNameAnsi);
|
|
|
|
if(arName==arAlloc)
|
|
GodotHeapFree(pNameAnsi);
|
|
if(arEnvironmentName==arAlloc)
|
|
GodotHeapFree(pEnvironmentAnsi);
|
|
if(arDriverName==arAlloc)
|
|
GodotHeapFree(pDriverNameAnsi);
|
|
|
|
if(arName == arFailed || arEnvironmentName == arFailed || arDriverName == arFailed)
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(RetVal);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=DeletePrintProcessorW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotDeletePrintProcessorW(LPWSTR pName, LPWSTR pEnvironment, LPWSTR pPrintProcessorName)
|
|
{
|
|
BOOL RetVal = FALSE;
|
|
LPSTR pNameAnsi = NULL;
|
|
LPSTR pEnvironmentAnsi = NULL;
|
|
LPSTR pPrintProcessorNameAnsi = NULL;
|
|
ALLOCRETURN arName = GodotToAcpOnHeap(pName, &pNameAnsi);
|
|
ALLOCRETURN arEnvironmentName = GodotToAcpOnHeap(pEnvironment, &pEnvironmentAnsi);
|
|
ALLOCRETURN arProcessorName = GodotToAcpOnHeap(pPrintProcessorName, &pPrintProcessorNameAnsi);
|
|
|
|
if(arName != arFailed && arEnvironmentName != arFailed && arProcessorName != arFailed)
|
|
RetVal = DeletePrintProcessorA(pNameAnsi, pEnvironmentAnsi, pPrintProcessorNameAnsi);
|
|
|
|
if(arName==arAlloc)
|
|
GodotHeapFree(pNameAnsi);
|
|
if(arEnvironmentName==arAlloc)
|
|
GodotHeapFree(pEnvironmentAnsi);
|
|
if(arProcessorName==arAlloc)
|
|
GodotHeapFree(pPrintProcessorNameAnsi);
|
|
|
|
if(arName == arFailed || arEnvironmentName == arFailed || arProcessorName == arFailed)
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(RetVal);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=DeletePrintProvidorW
|
|
Begin=
|
|
BOOL __stdcall GodotDeletePrintProvidorW(LPWSTR pName, LPWSTR pEnvironment, LPWSTR pPrintProvidorName)
|
|
{
|
|
BOOL RetVal = FALSE;
|
|
LPSTR pNameAnsi = NULL;
|
|
LPSTR pEnvironmentAnsi = NULL;
|
|
LPSTR pPrintProvidorNameAnsi = NULL;
|
|
ALLOCRETURN arName = GodotToAcpOnHeap(pName, &pNameAnsi);
|
|
ALLOCRETURN arEnvironmentName = GodotToAcpOnHeap(pEnvironment, &pEnvironmentAnsi);
|
|
ALLOCRETURN arPrintProvidorName = GodotToAcpOnHeap(pPrintProvidorName, &pPrintProvidorNameAnsi);
|
|
|
|
if(arName != arFailed && arEnvironmentName != arFailed && arPrintProvidorName != arFailed)
|
|
RetVal=DeletePrintProvidorWA(pNameAnsi, pEnvironmentAnsi, pPrintProvidorNameAnsi);
|
|
|
|
if(arName==arAlloc)
|
|
GodotHeapFree(pNameAnsi);
|
|
if(arEnvironmentName==arAlloc)
|
|
GodotHeapFree(pEnvironmentAnsi);
|
|
if(arPrintProvidorName==arAlloc)
|
|
GodotHeapFree(pPrintProvidorNameAnsi);
|
|
|
|
if(arName == arFailed || arEnvironmentName == arFailed || arPrintProvidorName == arFailed)
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(RetVal);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=DeviceCapabilitiesW
|
|
Begin=
|
|
int __stdcall
|
|
GodotDeviceCapabilitiesW(LPCWSTR pDevice, LPCWSTR pPort, WORD fwCapability, LPWSTR pOutput,
|
|
const DEVMODEW * pDevMode)
|
|
{
|
|
// UNSUPPORTED FUNCTION: Documented as a failure stub
|
|
LPCSTR pDeviceAnsi;
|
|
LPCSTR pPortAnsi;
|
|
int RetVal;
|
|
LPDEVMODEA pdma;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(pDevice, pDeviceAnsi);
|
|
GODOT_TO_ACP_STACKALLOC(pPort, pPortAnsi);
|
|
if((pDeviceAnsi==NULL && pDevice != NULL) ||
|
|
(pPortAnsi==NULL && pPort != NULL))
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
if(pDevMode==NULL)
|
|
pdma = NULL;
|
|
else
|
|
{
|
|
pdma = GodotHeapAlloc(sizeof(DEVMODEA) + pDevMode->dmDriverExtra);
|
|
if(pdma==NULL)
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(0);
|
|
}
|
|
DevModeAfromW(pdma, (LPDEVMODEW)pDevMode);
|
|
}
|
|
|
|
switch(fwCapability)
|
|
{
|
|
case DC_BINNAMES:
|
|
case DC_PAPERNAMES:
|
|
case DC_FILEDEPENDENCIES:
|
|
{
|
|
// Array of 24-char or 64-char strings, RetVal is the number of them
|
|
// The strings are null-terminated unless the name is 64 characters long.
|
|
|
|
// Always get the size, either because that is all
|
|
// the caller wanted or because we need it ourselves.
|
|
RetVal = DeviceCapabilitiesA(pDeviceAnsi, pPortAnsi, fwCapability, NULL, pdma);
|
|
|
|
if(pOutput!=NULL)
|
|
{
|
|
LPSTR pOutputAnsi;
|
|
size_t cchBuf = ((fwCapability==DC_BINNAMES ? 24 : 64) * RetVal);
|
|
|
|
_STACKALLOC((cchBuf * RetVal), pOutputAnsi);
|
|
if(pOutputAnsi==NULL)
|
|
{
|
|
if(pdma)
|
|
GodotHeapFree(pdma);
|
|
return(0);
|
|
}
|
|
|
|
RetVal = DeviceCapabilitiesA(pDeviceAnsi, pPortAnsi, fwCapability, pOutputAnsi, pdma);
|
|
if(RetVal > 0)
|
|
{
|
|
// Failure is -1 and 0 means nothing to convert so this
|
|
// is a good conditional for the conversion.
|
|
MultiByteToWideChar(g_acp, 0, pOutputAnsi, cchBuf, pOutput, cchBuf);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
case DC_BINS:
|
|
case DC_ENUMRESOLUTIONS:
|
|
case DC_PAPERS:
|
|
case DC_PAPERSIZE:
|
|
// Output param is an array of values (LONG or WORD or POINT)
|
|
// CONSIDER: Why bother will a special case here?
|
|
RetVal = DeviceCapabilitiesA(pDeviceAnsi, pPortAnsi, fwCapability, (LPSTR)pOutput, pdma);
|
|
break;
|
|
|
|
default:
|
|
// Output param is not used
|
|
RetVal = DeviceCapabilitiesA(pDeviceAnsi, pPortAnsi, fwCapability, (LPSTR)pOutput, pdma);
|
|
break;
|
|
}
|
|
|
|
if(pdma)
|
|
GodotHeapFree(pdma);
|
|
return(RetVal);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=DialogBoxIndirectParamW
|
|
Begin=
|
|
INT_PTR __stdcall
|
|
GodotDialogBoxIndirectParamW(HINSTANCE hInst, LPCDLGTEMPLATEW hdt, HWND hWnd, DLGPROC lpfn, LPARAM dwParam)
|
|
{
|
|
LPGODOTTLSINFO lpgti = GetThreadInfoSafe(TRUE);
|
|
|
|
if(!lpgti)
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(0);
|
|
}
|
|
else
|
|
{
|
|
INT_PTR RetVal;
|
|
|
|
INIT_WINDOW_SNIFF(lpgti->hHook);
|
|
lpgti->pfnDlgProc = lpfn;
|
|
RetVal = DialogBoxIndirectParamA(hInst, (LPCDLGTEMPLATEA)hdt, hWnd, &DialogProc, dwParam);
|
|
TERM_WINDOW_SNIFF(lpgti->hHook);
|
|
|
|
return(RetVal);
|
|
}
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=DialogBoxParamW
|
|
Begin=
|
|
INT_PTR __stdcall
|
|
GodotDialogBoxParamW(HINSTANCE hInst, LPCWSTR lpTemplate, HWND hWndParent, DLGPROC lpfn, LPARAM dwParam)
|
|
{
|
|
LPGODOTTLSINFO lpgti = GetThreadInfoSafe(TRUE);
|
|
|
|
if(!lpgti)
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(0);
|
|
}
|
|
else
|
|
{
|
|
INT_PTR RetVal;
|
|
LPSTR lpTemplateAnsi;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lpTemplate, lpTemplateAnsi);
|
|
lpgti->pfnDlgProc = lpfn;
|
|
INIT_WINDOW_SNIFF(lpgti->hHook);
|
|
RetVal=DialogBoxParamA(hInst, lpTemplateAnsi, hWndParent, &DialogProc, dwParam);
|
|
TERM_WINDOW_SNIFF(lpgti->hHook);
|
|
return RetVal;
|
|
}
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=DispatchMessageW
|
|
Begin=
|
|
LRESULT __stdcall
|
|
GodotDispatchMessageW(const MSG * lpMsg)
|
|
{
|
|
return(GodotDispatchMessage(mtDispatchMessage, NULL, NULL, (LPMSG)lpMsg));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=DlgDirListW
|
|
Begin=
|
|
int __stdcall
|
|
GodotDlgDirListW(HWND hDlg, LPWSTR lpPathSpec, int nIDListBox, int nIDStaticPath, UINT uFileType)
|
|
{
|
|
// Begin locals
|
|
int RetVal;
|
|
LPSTR lpPathSpecAnsi;
|
|
|
|
// Begin precall
|
|
GODOT_TO_ACP_STACKALLOC(lpPathSpec, lpPathSpecAnsi);
|
|
|
|
RetVal=DlgDirListA(hDlg, lpPathSpecAnsi, nIDListBox, nIDStaticPath, uFileType);
|
|
|
|
if(RetVal)
|
|
MultiByteToWideChar(g_acp, 0, lpPathSpecAnsi, -1, lpPathSpec, gwcslen(lpPathSpec));
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=DlgDirListComboBoxW
|
|
Begin=
|
|
int __stdcall
|
|
GodotDlgDirListComboBoxW(HWND hDlg, LPWSTR lpPathSpec, int nIDComboBox, int nIDStaticPath, UINT uFiletype)
|
|
{
|
|
// Begin locals
|
|
int RetVal;
|
|
LPSTR lpPathSpecAnsi;
|
|
|
|
// Begin precall
|
|
GODOT_TO_ACP_STACKALLOC(lpPathSpec, lpPathSpecAnsi);
|
|
|
|
RetVal=DlgDirListComboBoxA(hDlg, lpPathSpecAnsi, nIDComboBox, nIDStaticPath, uFiletype);
|
|
|
|
if(RetVal)
|
|
MultiByteToWideChar(g_acp, 0, lpPathSpecAnsi, -1, lpPathSpec, gwcslen(lpPathSpec));
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=DlgDirSelectComboBoxExW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotDlgDirSelectComboBoxExW(HWND hDlg, LPWSTR lpString, int nCount, int nIDComboBox)
|
|
{
|
|
BOOL RetVal;
|
|
LPSTR lpStringAnsi;
|
|
|
|
_STACKALLOC((nCount * g_mcs) + 1, lpStringAnsi);
|
|
if(!lpStringAnsi)
|
|
return(FALSE);
|
|
RetVal=DlgDirSelectComboBoxExA(hDlg, lpStringAnsi, nCount, nIDComboBox);
|
|
|
|
if(FSTRING_VALID(lpString) && FSTRING_VALID(lpStringAnsi))
|
|
MultiByteToWideChar(g_acp, 0, lpStringAnsi, -1, lpString, nCount);
|
|
else if(FSTRING_VALID(lpString))
|
|
{
|
|
lpString[0] = '\0';
|
|
}
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=DlgDirSelectExW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotDlgDirSelectExW(HWND hDlg, LPWSTR lpString, int nCount, int nIDListBox)
|
|
{
|
|
BOOL RetVal;
|
|
LPSTR lpStringAnsi;
|
|
|
|
_STACKALLOC((nCount * g_mcs) + 1, lpStringAnsi);
|
|
if(!lpStringAnsi)
|
|
{
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(FALSE);
|
|
}
|
|
RetVal=DlgDirSelectExA(hDlg, lpStringAnsi, nCount, nIDListBox);
|
|
|
|
if(FSTRING_VALID(lpString) && FSTRING_VALID(lpStringAnsi))
|
|
MultiByteToWideChar(g_acp, 0, lpStringAnsi, -1, lpString, nCount);
|
|
else if(FSTRING_VALID(lpString))
|
|
{
|
|
lpString[0] = '\0';
|
|
}
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=DocumentPropertiesW
|
|
Begin=
|
|
LONG __stdcall
|
|
GodotDocumentPropertiesW(HWND hWnd, HANDLE hPrinter, LPWSTR pDeviceName,
|
|
PDEVMODEW pDevModeOutput, PDEVMODEW pDevModeInput, DWORD fMode)
|
|
{
|
|
// UNSUPPORTED FUNCTION: Documented as a failure stub
|
|
LPDEVMODEA lpdmaOut = NULL;
|
|
LPDEVMODEA lpdmaIn = NULL;
|
|
LONG RetVal = 0;
|
|
LPSTR pDeviceNameAnsi = NULL;
|
|
ALLOCRETURN arDeviceName = GodotToAcpOnHeap(pDeviceName, &pDeviceNameAnsi);
|
|
|
|
if(arDeviceName==arFailed)
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(0);
|
|
}
|
|
|
|
if((fMode & DM_OUT_BUFFER) && pDevModeOutput)
|
|
{
|
|
LONG cb = DocumentPropertiesA(hWnd, hPrinter, pDeviceNameAnsi, NULL, NULL, 0);
|
|
_STACKALLOC(cb, lpdmaOut);
|
|
if(!lpdmaOut && (cb > 0))
|
|
{
|
|
if(arDeviceName==arAlloc)
|
|
GodotHeapFree(pDeviceNameAnsi);
|
|
return(0);
|
|
}
|
|
}
|
|
|
|
if((fMode & DM_IN_BUFFER) && pDevModeInput)
|
|
{
|
|
lpdmaIn = GodotHeapAlloc(sizeof(DEVMODEA) + (pDevModeInput ? pDevModeInput->dmDriverExtra : 0));
|
|
if(lpdmaIn==NULL)
|
|
{
|
|
if(arDeviceName==arAlloc)
|
|
GodotHeapFree(pDeviceNameAnsi);
|
|
return(0);
|
|
}
|
|
ZeroMemory(lpdmaIn, sizeof(DEVMODEA) + (pDevModeInput ? pDevModeInput->dmDriverExtra : 0));
|
|
DevModeAfromW(lpdmaIn, pDevModeInput);
|
|
}
|
|
|
|
RetVal = DocumentPropertiesA(hWnd, hPrinter, pDeviceNameAnsi, lpdmaOut, lpdmaIn, fMode);
|
|
|
|
if(fMode == 0)
|
|
{
|
|
// More accurate calculation of the DEVMODE size to return
|
|
RetVal += sizeof(DEVMODEW) - sizeof(DEVMODEA);
|
|
}
|
|
else if(RetVal==IDOK && (fMode & DM_OUT_BUFFER))
|
|
{
|
|
DevModeWfromA(pDevModeOutput, lpdmaOut);
|
|
}
|
|
|
|
if(arDeviceName==arAlloc)
|
|
GodotHeapFree(pDeviceNameAnsi);
|
|
if(lpdmaIn)
|
|
GodotHeapFree(lpdmaIn);
|
|
return(RetVal);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=DragQueryFileW
|
|
Begin=
|
|
UINT __stdcall
|
|
GodotDragQueryFileW(HDROP hDrop, UINT iFile, LPWSTR lpszFile, UINT cch)
|
|
{
|
|
UINT RetVal;
|
|
|
|
if(iFile != 0xFFFFFFFF)
|
|
{
|
|
LPSTR lpszFileAnsi;
|
|
|
|
if(lpszFile)
|
|
{
|
|
_STACKALLOC(cch * g_mcs, lpszFileAnsi);
|
|
if(lpszFileAnsi==NULL)
|
|
{
|
|
return(0);
|
|
}
|
|
ZeroMemory(lpszFileAnsi, cch * g_mcs);
|
|
}
|
|
else
|
|
lpszFileAnsi = NULL;
|
|
|
|
RetVal=DragQueryFileA(hDrop, iFile, lpszFileAnsi, cch);
|
|
|
|
if((RetVal > 0) && (lpszFile))
|
|
MultiByteToWideChar(g_acp, 0, lpszFileAnsi, -1, lpszFile, cch);
|
|
}
|
|
else
|
|
{
|
|
RetVal=DragQueryFileA(hDrop, iFile, (LPSTR)lpszFile, cch);
|
|
}
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=DrawTextW
|
|
Begin=
|
|
int __stdcall
|
|
GodotDrawTextW(HDC hDC, LPCWSTR lpString, int nCount, LPRECT lpRect, UINT uFormat)
|
|
{
|
|
int RetVal;
|
|
LPSTR lpStringAnsi;
|
|
BOOL fExtra =((uFormat & DT_MODIFYSTRING) &&
|
|
(uFormat & (DT_PATH_ELLIPSIS | DT_WORD_ELLIPSIS | DT_END_ELLIPSIS)));
|
|
int Adj = (fExtra ? 4 : 0);
|
|
UINT cpg = CpgFromHdc(hDC);
|
|
UINT mcs = CbPerChOfCpg(cpg);
|
|
|
|
if (FSTRING_VALID(lpString))
|
|
{
|
|
size_t lpStringLength = gwcslen(lpString) + 1;
|
|
|
|
_STACKALLOC((lpStringLength+Adj)*mcs, lpStringAnsi);
|
|
if(lpStringAnsi==NULL)
|
|
{
|
|
return(0);
|
|
}
|
|
WideCharToMultiByte(cpg, 0,
|
|
lpString, lpStringLength,
|
|
lpStringAnsi, (lpStringLength+Adj)*mcs,
|
|
NULL, NULL);
|
|
}
|
|
else
|
|
lpStringAnsi = (LPSTR)lpString;
|
|
|
|
RetVal=DrawTextA(hDC, lpStringAnsi, nCount, lpRect, uFormat);
|
|
|
|
// Note that lpString is only modified if fExtraChars is True
|
|
if (RetVal && fExtra)
|
|
MultiByteToWideChar(cpg, 0, lpStringAnsi, -1, (LPWSTR)lpString, (gwcslen(lpString) + Adj));
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=DrawTextExW
|
|
Begin=
|
|
int __stdcall
|
|
GodotDrawTextExW( HDC hdc,
|
|
LPWSTR lpchText,
|
|
int cchText,
|
|
LPRECT lprc,
|
|
UINT dwDTF,
|
|
LPDRAWTEXTPARAMS lpDTParams
|
|
)
|
|
{
|
|
int RetVal;
|
|
LPSTR lpchTextAnsi;
|
|
BOOL fExtra =((dwDTF & DT_MODIFYSTRING) &&
|
|
(dwDTF & (DT_PATH_ELLIPSIS | DT_WORD_ELLIPSIS | DT_END_ELLIPSIS)));
|
|
int Adj = (fExtra ? 4 : 0);
|
|
UINT cpg = CpgFromHdc(hdc);
|
|
UINT mcs = CbPerChOfCpg(cpg);
|
|
|
|
if (FSTRING_VALID(lpchText))
|
|
{
|
|
size_t lpchTextAnsiLength = gwcslen(lpchText) + 1;
|
|
|
|
_STACKALLOC((lpchTextAnsiLength+Adj)*mcs, lpchTextAnsi);
|
|
if(lpchTextAnsi==NULL)
|
|
{
|
|
return(0);
|
|
}
|
|
WideCharToMultiByte(cpg, 0,
|
|
lpchText, lpchTextAnsiLength,
|
|
lpchTextAnsi, (lpchTextAnsiLength+Adj)*mcs,
|
|
NULL, NULL);
|
|
}
|
|
else
|
|
lpchTextAnsi = (LPSTR)lpchText;
|
|
|
|
RetVal=DrawTextExA(hdc, lpchTextAnsi, cchText, lprc, dwDTF, lpDTParams);
|
|
|
|
// Note that lpString is only modified if fExtraChars is True
|
|
if (RetVal && fExtra)
|
|
MultiByteToWideChar(cpg, 0, lpchTextAnsi, -1, (LPWSTR)lpchText, (gwcslen(lpchText) + Adj));
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=EnableWindow
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotEnableWindow(HWND hWnd, BOOL bEnable)
|
|
{
|
|
// We wrap this API in order to get consistent behavior on both
|
|
// NT and Win9x. It seems that on NT, any non-zero value of bEnable
|
|
// will enable the window. Based on empirical data, Win9x seems to
|
|
// look at only the low 16 bits of bEnable. This causes a problem,
|
|
// for example, if the caller passes a count of items with the intent
|
|
// to enable a window when the count is >0. That will fail when the
|
|
// count is a multiple of 64K, but will be nearly impossible to find
|
|
// and fix the problem. See Visual Studio 7 bug # 178556 for an
|
|
// example of such a bug.
|
|
return(EnableWindow(hWnd, (bEnable != 0)));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=EndUpdateResourceW
|
|
Begin=
|
|
BOOL __stdcall GodotEndUpdateResourceW(HANDLE hUpdate, BOOL fDiscard)
|
|
{
|
|
// UNSUPPORTED FUNCTION: Documented as a failure stub
|
|
return(EndUpdateResourceInternalW(hUpdate, fDiscard));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=EnumCalendarInfoW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotEnumCalendarInfoW(CALINFO_ENUMPROCW lpCalInfoEnumProc, LCID Locale, CALID Calendar, CALTYPE CalType)
|
|
{
|
|
// Begin locals
|
|
BOOL RetVal = FALSE;
|
|
LPGODOTTLSINFO lpgti;
|
|
|
|
if(!(lpgti = GetThreadInfoSafe(TRUE)))
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(FALSE);
|
|
}
|
|
|
|
if((lpgti->pfnCalendarInfo &&
|
|
(lpgti->pfnCalendarInfo != lpCalInfoEnumProc)) ||
|
|
lpgti->cCalendarInfo >= GODOTMAXREFCOUNT)
|
|
{
|
|
// A hook is already defined and it is a different hook. We
|
|
// must fail the call here.
|
|
SetLastError(ERROR_INVALID_FILTER_PROC);
|
|
return(FALSE);
|
|
}
|
|
|
|
lpgti->pfnCalendarInfo = lpCalInfoEnumProc;
|
|
lpgti->cCalendarInfo++;
|
|
RetVal=EnumCalendarInfoA(&EnumCalendarInfoProc, Locale, Calendar, CalType);
|
|
lpgti->pfnCalendarInfo = NULL;
|
|
lpgti->cCalendarInfo--;
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=EnumCalendarInfoExW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotEnumCalendarInfoExW(CALINFO_ENUMPROCEXW lpEnumProcEx, LCID Locale, CALID Calendar, CALTYPE CalType)
|
|
{
|
|
// Begin locals
|
|
BOOL RetVal = FALSE;
|
|
|
|
if (s_pfnEnumCalendarInfoExA == NULL)
|
|
{
|
|
// Must allocate stuff for this API call
|
|
s_pfnEnumCalendarInfoExA = (PFNeciea)GetKernelProc("EnumCalendarInfoExA");
|
|
}
|
|
|
|
if (s_pfnEnumCalendarInfoExA)
|
|
{
|
|
LPGODOTTLSINFO lpgti;
|
|
|
|
if(!(lpgti = GetThreadInfoSafe(TRUE)))
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(FALSE);
|
|
}
|
|
|
|
if((lpgti->pfnCalendarInfoEx &&
|
|
(lpgti->pfnCalendarInfoEx != lpEnumProcEx)) ||
|
|
lpgti->cCalendarInfoEx >= GODOTMAXREFCOUNT)
|
|
{
|
|
// A hook is already defined and it is a different hook. We
|
|
// must fail the call here.
|
|
SetLastError(ERROR_INVALID_FILTER_PROC);
|
|
return(FALSE);
|
|
}
|
|
|
|
lpgti->pfnCalendarInfoEx = lpEnumProcEx;
|
|
lpgti->cCalendarInfoEx++;
|
|
RetVal = (s_pfnEnumCalendarInfoExA (&EnumCalendarInfoProcEx, Locale, Calendar, CalType ));
|
|
lpgti->pfnCalendarInfoEx = NULL;
|
|
lpgti->cCalendarInfoEx--;
|
|
}
|
|
else
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=EnumClipboardFormats
|
|
Begin=
|
|
UINT __stdcall
|
|
GodotEnumClipboardFormats(UINT uFormat)
|
|
{
|
|
UINT RetVal = EnumClipboardFormats(uFormat);
|
|
|
|
if((RetVal==0) && (GetLastError() == 0))
|
|
{
|
|
// The zero return with no error can mean one of three things to us:
|
|
// 1) uFormat is one of our faux formats that we told them is valid
|
|
// 2) uFormat is an entirely invalid format that is not really in anyone's chain
|
|
// 3) uFormat is the last legitimate member of the chain according to the system
|
|
|
|
BOOL fSystemLikes = IsClipboardFormatAvailable(uFormat);
|
|
BOOL fGodotLikes = GodotIsClipboardFormatAvailable(uFormat);
|
|
|
|
if(!fSystemLikes && fGodotLikes)
|
|
{
|
|
// This is case #1 above. Therefore, if this is CF_TEXT then
|
|
// we have one more to pass, otherwise we are done.
|
|
if(uFormat==CF_TEXT)
|
|
RetVal = CF_OEMTEXT;
|
|
}
|
|
else if(!fSystemLikes && !fGodotLikes)
|
|
{
|
|
// This is case #2 above, nothing to do here at all
|
|
}
|
|
else
|
|
{
|
|
// This is case #3 above: our hardest one to do. Basically, we have to
|
|
// add 0-2 formats to the chain:
|
|
// a) if system has CF_TEXT but not CF_UNICODETEXT, then we pass CF_UNICODETEXT
|
|
// b) if system has CF_UNICODETEXT but not CF_TEXT, then as pass CF_TEXT
|
|
// (CF_OEMTEXT will be passed next time via case #1 above)
|
|
// c) if system has neither, then we are done
|
|
|
|
if(IsClipboardFormatAvailable(CF_TEXT) && !IsClipboardFormatAvailable(CF_UNICODETEXT))
|
|
{
|
|
RetVal = CF_UNICODETEXT;
|
|
}
|
|
else if(IsClipboardFormatAvailable(CF_UNICODETEXT) && !IsClipboardFormatAvailable(CF_TEXT))
|
|
{
|
|
RetVal = CF_TEXT;
|
|
}
|
|
}
|
|
}
|
|
|
|
return(RetVal);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=EnumDateFormatsW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotEnumDateFormatsW(DATEFMT_ENUMPROCW lpDateFmtEnumProc, LCID Locale, DWORD dwFlags)
|
|
{
|
|
// Begin locals
|
|
BOOL RetVal = FALSE;
|
|
LPGODOTTLSINFO lpgti;
|
|
|
|
if(!(lpgti = GetThreadInfoSafe(TRUE)))
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(FALSE);
|
|
}
|
|
|
|
if((lpgti->pfnDateFormats &&
|
|
(lpgti->pfnDateFormats != lpDateFmtEnumProc)) ||
|
|
lpgti->cDateFormats >= GODOTMAXREFCOUNT)
|
|
{
|
|
// A hook is already defined and it is a different hook. We
|
|
// must fail the call here.
|
|
SetLastError(ERROR_INVALID_FILTER_PROC);
|
|
return(FALSE);
|
|
}
|
|
|
|
lpgti->pfnDateFormats = lpDateFmtEnumProc;
|
|
lpgti->cDateFormats++;
|
|
RetVal=EnumDateFormatsA(&EnumDateFormatsProc, Locale, dwFlags);
|
|
lpgti->pfnDateFormats = NULL;
|
|
lpgti->cDateFormats--;
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=EnumDateFormatsExW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotEnumDateFormatsExW(DATEFMT_ENUMPROCEXW lpDateFmtEnumProcEx, LCID Locale, DWORD dwFlags)
|
|
{
|
|
// Begin locals
|
|
BOOL RetVal = FALSE;
|
|
|
|
if (s_pfnEnumDateFormatsExA == NULL)
|
|
{
|
|
// Must allocate stuff for this API call
|
|
s_pfnEnumDateFormatsExA = (PFNedfea)GetKernelProc("EnumDateFormatsExA");
|
|
}
|
|
|
|
if (s_pfnEnumDateFormatsExA)
|
|
{
|
|
LPGODOTTLSINFO lpgti;
|
|
|
|
if(!(lpgti = GetThreadInfoSafe(TRUE)))
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(FALSE);
|
|
}
|
|
|
|
if((lpgti->pfnDateFormatsEx &&
|
|
(lpgti->pfnDateFormatsEx != lpDateFmtEnumProcEx)) ||
|
|
lpgti->cDateFormats >= GODOTMAXREFCOUNT)
|
|
{
|
|
// A hook is already defined and it is a different hook. We
|
|
// must fail the call here.
|
|
SetLastError(ERROR_INVALID_FILTER_PROC);
|
|
return(FALSE);
|
|
}
|
|
|
|
lpgti->pfnDateFormatsEx = lpDateFmtEnumProcEx;
|
|
lpgti->cDateFormats++;
|
|
RetVal = (s_pfnEnumDateFormatsExA (&EnumDateFormatsProcEx, Locale, dwFlags));
|
|
lpgti->pfnDateFormatsEx = NULL;
|
|
lpgti->cDateFormats--;
|
|
}
|
|
else
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=EnumDisplayDevicesW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotEnumDisplayDevicesW(LPCWSTR lpDevice, DWORD iDevNum, PDISPLAY_DEVICEW pddw, DWORD dwFlags)
|
|
{
|
|
BOOL RetVal = FALSE;
|
|
|
|
if (!s_pfnEnumDisplayDevicesA)
|
|
// Must allocate stuff for this API call
|
|
s_pfnEnumDisplayDevicesA = (PFNedda)GetUserProc("EnumDisplayDevicesA");
|
|
|
|
if (s_pfnEnumDisplayDevicesA)
|
|
{
|
|
LPSTR lpDeviceAnsi;
|
|
DISPLAY_DEVICEA dda;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lpDevice, lpDeviceAnsi);
|
|
ZeroMemory(&dda, sizeof(DISPLAY_DEVICEA));
|
|
dda.cb = sizeof(DISPLAY_DEVICEA);
|
|
|
|
RetVal = (s_pfnEnumDisplayDevicesA(lpDeviceAnsi, iDevNum, &dda, dwFlags));
|
|
|
|
if(RetVal)
|
|
{
|
|
MultiByteToWideChar(g_acp, 0, dda.DeviceName, -1, pddw->DeviceName, 32);
|
|
MultiByteToWideChar(g_acp, 0, dda.DeviceString, -1, pddw->DeviceString, 128);
|
|
pddw->StateFlags = dda.StateFlags;
|
|
MultiByteToWideChar(g_acp, 0, dda.DeviceID, -1, pddw->DeviceID, 128);
|
|
MultiByteToWideChar(g_acp, 0, dda.DeviceKey, -1, pddw->DeviceKey, 128);
|
|
}
|
|
}
|
|
else
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=EnumDisplaySettingsW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotEnumDisplaySettingsW(LPCWSTR lpszDeviceName, DWORD iModeNum, LPDEVMODEW lpDevMode)
|
|
{
|
|
// Begin locals
|
|
BOOL RetVal;
|
|
LPSTR lpszDeviceNameAnsi;
|
|
DEVMODEA dma;
|
|
|
|
// Begin precall
|
|
GODOT_TO_ACP_STACKALLOC(lpszDeviceName, lpszDeviceNameAnsi);
|
|
if(!lpszDeviceNameAnsi && lpszDeviceName)
|
|
return(FALSE);
|
|
|
|
RetVal=EnumDisplaySettingsA(lpszDeviceNameAnsi, iModeNum, &dma);
|
|
|
|
if(RetVal && lpDevMode)
|
|
{
|
|
// We assume that lpDevMode will have room for the extra bytes, if any
|
|
DevModeWfromA(lpDevMode, &dma);
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=EnumDisplaySettingsExW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotEnumDisplaySettingsExW(LPCWSTR lpszDeviceName, DWORD iModeNum, LPDEVMODEW lpDevMode, DWORD dwFlags)
|
|
{
|
|
// Begin locals
|
|
BOOL RetVal = FALSE;
|
|
|
|
if (s_pfnEnumDisplaySettingsExA == NULL)
|
|
{
|
|
// Must allocate stuff for this API call
|
|
s_pfnEnumDisplaySettingsExA = (PFNedsea)GetUserProc("EnumDisplaySettingsExA");
|
|
}
|
|
|
|
if (s_pfnEnumDisplaySettingsExA)
|
|
{
|
|
LPSTR lpszDeviceNameAnsi;
|
|
DEVMODEA dma;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lpszDeviceName, lpszDeviceNameAnsi);
|
|
if(!lpszDeviceNameAnsi && lpszDeviceName)
|
|
return(FALSE);
|
|
|
|
ZeroMemory(&dma, sizeof(DEVMODEA));
|
|
dma.dmSize = sizeof(DEVMODEA);
|
|
|
|
RetVal = (s_pfnEnumDisplaySettingsExA(lpszDeviceNameAnsi, iModeNum, &dma, dwFlags));
|
|
|
|
if(RetVal && lpDevMode)
|
|
{
|
|
// We assume that lpDevMode will have room for the extra bytes, if any
|
|
DevModeWfromA(lpDevMode, &dma);
|
|
}
|
|
|
|
}
|
|
else
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=EnumerateSecurityPackagesW
|
|
Begin=
|
|
SECURITY_STATUS __stdcall
|
|
GodotEnumerateSecurityPackagesW(unsigned long int * pcPackages, PSecPkgInfoW * ppPackageInfo)
|
|
{
|
|
// ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
|
|
return(SEC_E_UNSUPPORTED_FUNCTION);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=EnumFontFamiliesW
|
|
Begin=
|
|
int __stdcall
|
|
GodotEnumFontFamiliesW(HDC hdc, LPCWSTR lpszFamily, FONTENUMPROCW lpEnumFontFamProc, LPARAM lParam)
|
|
{
|
|
// Begin locals
|
|
int RetVal;
|
|
LPSTR lpszFamilyAnsi;
|
|
LPGODOTTLSINFO lpgti;
|
|
|
|
if(!(lpgti = GetThreadInfoSafe(TRUE)))
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(0);
|
|
}
|
|
|
|
if((lpgti->pfnFontFamilies &&
|
|
(lpgti->pfnFontFamilies != lpEnumFontFamProc)) ||
|
|
lpgti->cFontFamilies >= GODOTMAXREFCOUNT)
|
|
{
|
|
// A hook is already defined and it is a different hook. We
|
|
// must fail the call here.
|
|
SetLastError(ERROR_INVALID_FILTER_PROC);
|
|
return(0);
|
|
}
|
|
|
|
lpgti->pfnFontFamilies = lpEnumFontFamProc;
|
|
lpgti->cFontFamilies++;
|
|
GODOT_TO_ACP_STACKALLOC(lpszFamily, lpszFamilyAnsi);
|
|
|
|
RetVal=EnumFontFamiliesA(hdc, lpszFamilyAnsi, (FONTENUMPROCA)&EnumFontFamProc, lParam);
|
|
|
|
lpgti->pfnFontFamilies = NULL;
|
|
lpgti->cFontFamilies--;
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=EnumFontFamiliesExW
|
|
Begin=
|
|
int __stdcall
|
|
GodotEnumFontFamiliesExW( HDC hdc,
|
|
LPLOGFONTW lpLogfont,
|
|
FONTENUMPROCW lpEnumFontFamExProc,
|
|
LPARAM lParam,
|
|
DWORD dwFlags
|
|
)
|
|
{
|
|
// Begin locals
|
|
int RetVal;
|
|
LOGFONTA lfa;
|
|
LPGODOTTLSINFO lpgti;
|
|
|
|
if(!(lpgti = GetThreadInfoSafe(TRUE)))
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(0);
|
|
}
|
|
|
|
if((lpgti->pfnFontFamiliesEx &&
|
|
(lpgti->pfnFontFamiliesEx != lpEnumFontFamExProc)) ||
|
|
lpgti->cFontFamiliesEx >= GODOTMAXREFCOUNT)
|
|
{
|
|
// A hook is already defined and it is a different hook. We
|
|
// must fail the call here.
|
|
SetLastError(ERROR_INVALID_FILTER_PROC);
|
|
return(0);
|
|
}
|
|
|
|
lpgti->pfnFontFamiliesEx = lpEnumFontFamExProc;
|
|
lpgti->cFontFamiliesEx++;
|
|
ZeroMemory(&lfa, sizeof(LOGFONTA));
|
|
LogFontAfromW(&lfa, lpLogfont);
|
|
|
|
RetVal=EnumFontFamiliesExA(hdc, &lfa, (FONTENUMPROCA)&EnumFontFamExProc, lParam, dwFlags);
|
|
lpgti->pfnFontFamiliesEx = NULL;
|
|
lpgti->cFontFamiliesEx--;
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=EnumFontsW
|
|
Begin=
|
|
int __stdcall
|
|
GodotEnumFontsW(HDC hdc, LPCWSTR lpFaceName, FONTENUMPROCW lpFontFunc, LPARAM lParam)
|
|
{
|
|
// Begin locals
|
|
int RetVal;
|
|
LPSTR lpFaceNameAnsi;
|
|
LPGODOTTLSINFO lpgti;
|
|
|
|
if(!(lpgti = GetThreadInfoSafe(TRUE)))
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(0);
|
|
}
|
|
|
|
if((lpgti->pfnFonts &&
|
|
(lpgti->pfnFonts != lpFontFunc)) ||
|
|
lpgti->cFonts >= GODOTMAXREFCOUNT)
|
|
{
|
|
// A hook is already defined and it is a different hook. We
|
|
// must fail the call here.
|
|
SetLastError(ERROR_INVALID_FILTER_PROC);
|
|
return(0);
|
|
}
|
|
|
|
lpgti->pfnFonts = lpFontFunc;
|
|
lpgti->cFonts++;
|
|
GODOT_TO_ACP_STACKALLOC(lpFaceName, lpFaceNameAnsi);
|
|
RetVal=EnumFontsA(hdc, lpFaceNameAnsi, &EnumFontsProc, lParam);
|
|
lpgti->pfnFonts = NULL;
|
|
lpgti->cFonts--;
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=EnumICMProfilesW
|
|
Begin=
|
|
int __stdcall
|
|
GodotEnumICMProfilesW(HDC hDC, ICMENUMPROCW lpEnumICMProfilesFunc, LPARAM lParam)
|
|
{
|
|
// Begin locals
|
|
int RetVal;
|
|
LPGODOTTLSINFO lpgti;
|
|
|
|
if(!(lpgti = GetThreadInfoSafe(TRUE)))
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(0);
|
|
}
|
|
|
|
if((lpgti->pfnICMProfiles &&
|
|
(lpgti->pfnICMProfiles != lpEnumICMProfilesFunc)) ||
|
|
lpgti->cICMProfiles >= GODOTMAXREFCOUNT)
|
|
{
|
|
// A hook is already defined and it is a different hook. We
|
|
// must fail the call here.
|
|
SetLastError(ERROR_INVALID_FILTER_PROC);
|
|
return(0);
|
|
}
|
|
|
|
lpgti->pfnICMProfiles = lpEnumICMProfilesFunc;
|
|
lpgti->cICMProfiles++;
|
|
RetVal=EnumICMProfilesA(hDC, &EnumICMProfilesProcCallback, lParam);
|
|
lpgti->pfnICMProfiles = NULL;
|
|
lpgti->cICMProfiles--;
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=EnumMonitorsW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotEnumMonitorsW(LPWSTR _noname0, DWORD _noname1, LPBYTE _noname2, DWORD _noname3,
|
|
LPDWORD _noname4, LPDWORD _noname5)
|
|
{
|
|
// ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
|
|
return(EnumMonitorsW(_noname0, _noname1, _noname2, _noname3, _noname4, _noname5));
|
|
}
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=EnumPortsW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotEnumPortsW(LPWSTR _noname0, DWORD _noname1, LPBYTE _noname2, DWORD _noname3,
|
|
LPDWORD _noname4, LPDWORD _noname5)
|
|
{
|
|
// ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
|
|
return(EnumPortsW(_noname0, _noname1, _noname2, _noname3, _noname4, _noname5));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=EnumPrinterDriversW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotEnumPrinterDriversW(LPWSTR _noname0, LPWSTR _noname1, DWORD _noname2, LPBYTE _noname3,
|
|
DWORD _noname4, LPDWORD _noname5, LPDWORD _noname6)
|
|
{
|
|
// ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
|
|
return(EnumPrinterDriversW(_noname0, _noname1, _noname2, _noname3, _noname4, _noname5, _noname6));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=EnumPrintersW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotEnumPrintersW(DWORD _noname0, LPWSTR _noname1, DWORD _noname2, LPBYTE _noname3,
|
|
DWORD _noname4, LPDWORD _noname5, LPDWORD _noname6)
|
|
{
|
|
// ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
|
|
return(EnumPrintersW(_noname0, _noname1, _noname2, _noname3, _noname4, _noname5, _noname6));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=EnumPrintProcessorDatatypesW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotEnumPrintProcessorDatatypesW(LPWSTR _noname0, LPWSTR _noname1, DWORD _noname2, LPBYTE _noname3,
|
|
DWORD _noname4, LPDWORD _noname5, LPDWORD _noname6)
|
|
{
|
|
// ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
|
|
return(EnumPrintProcessorDatatypesW(_noname0, _noname1, _noname2, _noname3,
|
|
_noname4, _noname5, _noname6));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=EnumPrintProcessorsW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotEnumPrintProcessorsW(LPWSTR pName, LPWSTR pEnvironment,
|
|
DWORD Level, LPBYTE pPrintProcessorInfo,
|
|
DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
|
|
{
|
|
// UNSUPPORTED FUNCTION: Documented as a failure stub
|
|
LPSTR pNameA, pEnvironmentA;
|
|
BOOL RetVal;
|
|
DWORD cbNeeded = 0;
|
|
DWORD cReturned = 0;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(pName, pNameA);
|
|
GODOT_TO_ACP_STACKALLOC(pEnvironment, pEnvironmentA);
|
|
if((!pNameA && pName) ||
|
|
(!pEnvironmentA && pEnvironment))
|
|
{
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(FALSE);
|
|
}
|
|
|
|
if(pPrintProcessorInfo==NULL || cbBuf==0)
|
|
{
|
|
RetVal = EnumPrintProcessorsA(pNameA, pEnvironmentA, Level, NULL, 0, &cbNeeded, &cReturned);
|
|
|
|
// Note that the size we return is potentially twice as
|
|
// big as it needs to be on DBCS platforms. Unfortunate,
|
|
// but there is not much else we can do.
|
|
if(RetVal==FALSE && GetLastError()== ERROR_INSUFFICIENT_BUFFER && pcbNeeded)
|
|
*pcbNeeded = cbNeeded * sizeof(WCHAR);
|
|
if(pcReturned)
|
|
*pcReturned = cReturned;
|
|
}
|
|
|
|
else
|
|
{
|
|
LPBYTE pPrintProcessorInfoA;
|
|
DWORD cbBufA = (FDBCS_CPG(g_acp ? cbBuf : cbBuf / 2));
|
|
|
|
_STACKALLOC(cbBufA, pPrintProcessorInfoA);
|
|
if(pPrintProcessorInfoA==NULL)
|
|
{
|
|
return(FALSE);
|
|
}
|
|
RetVal = EnumPrintProcessorsA(pNameA, pEnvironmentA, Level, pPrintProcessorInfoA, cbBufA,
|
|
&cbNeeded, &cReturned);
|
|
if(RetVal==FALSE && GetLastError()== ERROR_INSUFFICIENT_BUFFER && pcbNeeded)
|
|
*pcbNeeded = cbNeeded * sizeof(WCHAR);
|
|
else if(RetVal)
|
|
{
|
|
PPRINTPROCESSOR_INFO_1W pPPIW = (PPRINTPROCESSOR_INFO_1W)pPrintProcessorInfo;
|
|
PPRINTPROCESSOR_INFO_1A pPPIA = (PPRINTPROCESSOR_INFO_1A)pPrintProcessorInfoA;
|
|
DWORD dwOffsetStr = (sizeof(PRINTPROCESSOR_INFO_1A) * cReturned);
|
|
DWORD ippi;
|
|
int cch = 0;
|
|
|
|
cbBufA -= dwOffsetStr;
|
|
for(ippi = 0; ippi < cReturned ; ippi++)
|
|
{
|
|
LPWSTR lpwz = (LPWSTR)pPrintProcessorInfo + dwOffsetStr;
|
|
cch = MultiByteToWideChar(g_acp, 0, pPPIA[ippi].pName, -1, lpwz, cbBufA/sizeof(WCHAR));
|
|
pPPIW[ippi].pName = lpwz;
|
|
dwOffsetStr += cch;
|
|
cbBufA -= cch;
|
|
}
|
|
if(pcbNeeded)
|
|
*pcbNeeded = dwOffsetStr + cch - (DWORD)pPrintProcessorInfo;
|
|
}
|
|
if(pcReturned)
|
|
*pcReturned = cReturned;
|
|
}
|
|
|
|
return(RetVal);
|
|
}
|
|
|
|
End=
|
|
|
|
|
|
[EFunc]
|
|
TemplateName=EnumPropsA
|
|
Begin=
|
|
int __stdcall
|
|
GodotEnumPropsA(HWND hWnd, PROPENUMPROCA lpEnumFunc)
|
|
{
|
|
// Begin locals
|
|
int RetVal = 0;
|
|
LPGODOTTLSINFO lpgti;
|
|
|
|
if(!(lpgti = GetThreadInfoSafe(TRUE)))
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(0);
|
|
}
|
|
|
|
if((lpgti->pfnPropA &&
|
|
(lpgti->pfnPropA != lpEnumFunc)) ||
|
|
lpgti->cPropA >= GODOTMAXREFCOUNT)
|
|
{
|
|
// A hook is already defined and it is a different hook. We
|
|
// must fail the call here.
|
|
SetLastError(ERROR_INVALID_FILTER_PROC);
|
|
return(0);
|
|
}
|
|
|
|
lpgti->pfnPropA = lpEnumFunc;
|
|
lpgti->cPropA++;
|
|
RetVal=EnumPropsA(hWnd, &PropEnumProcA);
|
|
lpgti->pfnPropA = NULL;
|
|
lpgti->cPropA--;
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=EnumPropsW
|
|
Begin=
|
|
int __stdcall
|
|
GodotEnumPropsW(HWND hWnd, PROPENUMPROCW lpEnumFunc)
|
|
{
|
|
// Begin locals
|
|
int RetVal = 0;
|
|
LPGODOTTLSINFO lpgti;
|
|
|
|
if(!(lpgti = GetThreadInfoSafe(TRUE)))
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(0);
|
|
}
|
|
|
|
if((lpgti->pfnProp &&
|
|
(lpgti->pfnProp != lpEnumFunc)) ||
|
|
lpgti->cProp >= GODOTMAXREFCOUNT)
|
|
{
|
|
// A hook is already defined and it is a different hook. We
|
|
// must fail the call here.
|
|
SetLastError(ERROR_INVALID_FILTER_PROC);
|
|
return(0);
|
|
}
|
|
|
|
lpgti->pfnProp = lpEnumFunc;
|
|
lpgti->cProp++;
|
|
RetVal=EnumPropsA(hWnd, &PropEnumProc);
|
|
lpgti->pfnProp = NULL;
|
|
lpgti->cProp--;
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=EnumPropsExA
|
|
Begin=
|
|
int __stdcall
|
|
GodotEnumPropsExA(HWND hWnd, PROPENUMPROCEXA lpEnumFunc, LPARAM lParam)
|
|
{
|
|
// Begin locals
|
|
int RetVal;
|
|
LPGODOTTLSINFO lpgti;
|
|
|
|
if(!(lpgti = GetThreadInfoSafe(TRUE)))
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(0);
|
|
}
|
|
|
|
if((lpgti->pfnPropExA &&
|
|
(lpgti->pfnPropExA != lpEnumFunc)) ||
|
|
lpgti->cPropExA >= GODOTMAXREFCOUNT)
|
|
{
|
|
// A hook is already defined and it is a different hook. We
|
|
// must fail the call here.
|
|
SetLastError(ERROR_INVALID_FILTER_PROC);
|
|
return(0);
|
|
}
|
|
|
|
lpgti->pfnPropExA = lpEnumFunc;
|
|
lpgti->cPropExA++;
|
|
RetVal=EnumPropsExA(hWnd, &PropEnumProcExA, lParam);
|
|
lpgti->pfnPropExA = NULL;
|
|
lpgti->cPropExA--;
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=EnumPropsExW
|
|
Begin=
|
|
int __stdcall
|
|
GodotEnumPropsExW(HWND hWnd, PROPENUMPROCEXW lpEnumFunc, LPARAM lParam)
|
|
{
|
|
// Begin locals
|
|
int RetVal;
|
|
LPGODOTTLSINFO lpgti;
|
|
|
|
if(!(lpgti = GetThreadInfoSafe(TRUE)))
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(0);
|
|
}
|
|
|
|
if((lpgti->pfnPropEx &&
|
|
(lpgti->pfnPropEx != lpEnumFunc)) ||
|
|
lpgti->cPropEx >= GODOTMAXREFCOUNT)
|
|
{
|
|
// A hook is already defined and it is a different hook. We
|
|
// must fail the call here.
|
|
SetLastError(ERROR_INVALID_FILTER_PROC);
|
|
return(0);
|
|
}
|
|
|
|
lpgti->pfnPropEx = lpEnumFunc;
|
|
lpgti->cPropEx++;
|
|
RetVal=EnumPropsExA(hWnd, &PropEnumProcEx, lParam);
|
|
lpgti->pfnPropEx = NULL;
|
|
lpgti->cPropEx--;
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=EnumSystemCodePagesW
|
|
Begin=
|
|
#define NLS_CODEPAGE_KEY "SYSTEM\\CurrentControlSet\\Control\\nls\\codepage"
|
|
#define MAX_KEYVALUEFULLINFO 256 /* max string length for key value full info */
|
|
#define ENUM_MAX_CP_SIZE 6 /* max size for cp id in registry */
|
|
|
|
BOOL __stdcall
|
|
GodotEnumSystemCodePagesW(CODEPAGE_ENUMPROCW lpCodePageEnumProc, DWORD dwFlags)
|
|
{
|
|
// Begin locals
|
|
BOOL fInstalled;
|
|
BOOL fCallEnumProc;
|
|
HKEY hKey;
|
|
LPSTR lpszValue;
|
|
LPSTR lpszData;
|
|
WCHAR wzValueString[MAX_KEYVALUEFULLINFO];
|
|
BYTE pStatic1[MAX_KEYVALUEFULLINFO];
|
|
BYTE pStatic2[MAX_KEYVALUEFULLINFO];
|
|
ULONG cbValue; /* size of value */
|
|
ULONG cbData; /* # bytes written Data */
|
|
DWORD dwIndex = 0;
|
|
DWORD dwType;
|
|
LONG rc;
|
|
BOOL fCancel = FALSE;
|
|
|
|
// Invalid Parameter Check:
|
|
// (function pointer is null)
|
|
if (lpCodePageEnumProc == NULL)
|
|
{
|
|
SetLastError( ERROR_INVALID_PARAMETER );
|
|
return ( FALSE );
|
|
}
|
|
|
|
|
|
// Invalid Flags Check:
|
|
// - flags other than valid ones
|
|
// - more than one of either supported or installed
|
|
if ( (dwFlags != CP_INSTALLED) &&
|
|
(dwFlags != CP_SUPPORTED) )
|
|
{
|
|
SetLastError(ERROR_INVALID_FLAGS);
|
|
return (FALSE);
|
|
}
|
|
|
|
|
|
// Initialize flag option.
|
|
fInstalled = dwFlags & CP_INSTALLED;
|
|
|
|
// Loop through the code page ids in the registry, call the function
|
|
// pointer for each one that meets the flag criteria.
|
|
|
|
// End loop if either FALSE is returned from the callback function
|
|
// or the end of the list is reached.
|
|
|
|
// Always need to ignore the ACP, OEMCP, MACCP, and OEMHAL entries.
|
|
|
|
if (ERROR_SUCCESS != RegOpenKeyExA(HKEY_LOCAL_MACHINE, NLS_CODEPAGE_KEY, 0, KEY_QUERY_VALUE, &hKey) )
|
|
{
|
|
SetLastError(ERROR_BADDB);
|
|
return (FALSE);
|
|
}
|
|
|
|
// Initialize some buffers
|
|
ZeroMemory(pStatic1, MAX_KEYVALUEFULLINFO);
|
|
ZeroMemory(pStatic2, MAX_KEYVALUEFULLINFO);
|
|
lpszValue = (LPSTR)pStatic1;
|
|
lpszData = (LPSTR)pStatic2;
|
|
cbValue = MAX_KEYVALUEFULLINFO;
|
|
cbData = MAX_KEYVALUEFULLINFO;
|
|
|
|
// Call the first time
|
|
rc = RegEnumValueA(hKey, dwIndex, lpszValue, &cbValue, NULL, &dwType, (LPBYTE)lpszData, &cbData);
|
|
|
|
while (rc != ERROR_NO_MORE_ITEMS)
|
|
{
|
|
fCallEnumProc = TRUE;
|
|
if (rc != ERROR_SUCCESS)
|
|
{
|
|
// If we get a different error, then the registry
|
|
// is corrupt. Just return FALSE.
|
|
SetLastError(ERROR_BADDB);
|
|
RegCloseKey(hKey);
|
|
return (FALSE);
|
|
}
|
|
|
|
// Check character size of the system CodePage value
|
|
if ( (cbValue >= ENUM_MAX_CP_SIZE) ||
|
|
((*lpszValue < '0') || (*lpszValue > '9')) )
|
|
fCallEnumProc = FALSE;
|
|
|
|
// Check flag to call the callback function and size of CodePage value.
|
|
if (fCallEnumProc)
|
|
{
|
|
if ( !fInstalled || (fInstalled && (*lpszData)) )
|
|
{
|
|
// Convert the string to Unicode
|
|
ZeroMemory(wzValueString, MAX_KEYVALUEFULLINFO * sizeof(WCHAR));
|
|
MultiByteToWideChar(g_acp, 0, lpszValue, -1, wzValueString, MAX_KEYVALUEFULLINFO - 1);
|
|
|
|
// Call the callback function.
|
|
if (((*lpCodePageEnumProc)(wzValueString)) != TRUE)
|
|
{
|
|
fCancel = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Increment enumeration index value and get the next enumeration.
|
|
// Initialize buffer of system locale value & data variables
|
|
dwIndex++;
|
|
ZeroMemory(pStatic1, MAX_KEYVALUEFULLINFO);
|
|
ZeroMemory(pStatic2, MAX_KEYVALUEFULLINFO);
|
|
|
|
lpszValue = (LPSTR)pStatic1;
|
|
lpszData = (LPSTR)pStatic2;
|
|
|
|
cbValue = MAX_KEYVALUEFULLINFO;
|
|
cbData = MAX_KEYVALUEFULLINFO;
|
|
|
|
rc = RegEnumValueA(hKey, dwIndex, lpszValue, &cbValue, NULL, &dwType, (LPBYTE)lpszData, &cbData);
|
|
}
|
|
|
|
// If they have not cancelled yet, tack on custom ones
|
|
if(!fCancel)
|
|
{
|
|
// UTF-7
|
|
if ((* lpCodePageEnumProc)(L"65000"))
|
|
{
|
|
// UTF-8
|
|
if ((* lpCodePageEnumProc)(L"65001"))
|
|
{
|
|
// GB 18030: we test the "installed" bit by whether or not
|
|
// we can get a handle to the DLL via our LoadLibrary call.
|
|
if(!fInstalled || (fInstalled && GetGB18030Handle()))
|
|
(* lpCodePageEnumProc)(L"54936");
|
|
}
|
|
}
|
|
}
|
|
|
|
// Returns success if we made it this far, even if they cancelled
|
|
RegCloseKey(hKey);
|
|
return(TRUE);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=EnumSystemLocalesW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotEnumSystemLocalesW(LOCALE_ENUMPROCW lpLocaleEnumProc, DWORD dwFlags)
|
|
{
|
|
// Begin locals
|
|
BOOL RetVal;
|
|
LPGODOTTLSINFO lpgti;
|
|
|
|
if(!(lpgti = GetThreadInfoSafe(TRUE)))
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(FALSE);
|
|
}
|
|
|
|
if((lpgti->pfnLocales &&
|
|
(lpgti->pfnLocales != lpLocaleEnumProc)) ||
|
|
lpgti->cLocales >= GODOTMAXREFCOUNT)
|
|
{
|
|
// A hook is already defined and it is a different hook. We
|
|
// must fail the call here.
|
|
SetLastError(ERROR_INVALID_FILTER_PROC);
|
|
return(FALSE);
|
|
}
|
|
|
|
lpgti->pfnLocales = lpLocaleEnumProc;
|
|
RetVal=EnumSystemLocalesA(&EnumLocalesProc, dwFlags);
|
|
lpgti->pfnLocales = NULL;
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=EnumTimeFormatsW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotEnumTimeFormatsW(TIMEFMT_ENUMPROCW lpTimeFmtEnumProc, LCID Locale, DWORD dwFlags)
|
|
{
|
|
// Begin locals
|
|
BOOL RetVal;
|
|
LPGODOTTLSINFO lpgti;
|
|
|
|
if(!(lpgti = GetThreadInfoSafe(TRUE)))
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(FALSE);
|
|
}
|
|
|
|
if((lpgti->pfnTimeFormats &&
|
|
(lpgti->pfnTimeFormats != lpTimeFmtEnumProc)) ||
|
|
lpgti->cTimeFormats >= GODOTMAXREFCOUNT)
|
|
{
|
|
// A hook is already defined and it is a different hook. We
|
|
// must fail the call here.
|
|
SetLastError(ERROR_INVALID_FILTER_PROC);
|
|
return(FALSE);
|
|
}
|
|
|
|
lpgti->pfnTimeFormats = lpTimeFmtEnumProc;
|
|
lpgti->cTimeFormats++;
|
|
RetVal=EnumTimeFormatsA(&EnumTimeFormatsProc, Locale, dwFlags);
|
|
lpgti->pfnTimeFormats = NULL;
|
|
lpgti->cTimeFormats--;
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=ExpandEnvironmentStringsW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotExpandEnvironmentStringsW(LPCWSTR lpSrc, LPWSTR lpDst, DWORD nSize)
|
|
{
|
|
// Begin locals
|
|
DWORD RetVal;
|
|
LPSTR lpSrcAnsi;
|
|
LPSTR lpDstAnsi;
|
|
|
|
_STACKALLOC((nSize*g_mcs)+1, lpDstAnsi);
|
|
GODOT_TO_ACP_STACKALLOC(lpSrc, lpSrcAnsi);
|
|
if((!lpSrcAnsi && lpSrc) ||
|
|
(!lpDstAnsi))
|
|
{
|
|
return(0);
|
|
}
|
|
ZeroMemory(lpDstAnsi, (nSize*g_mcs)+1);
|
|
|
|
RetVal=ExpandEnvironmentStringsA(lpSrcAnsi, lpDstAnsi, nSize);
|
|
|
|
if(RetVal <= nSize)
|
|
{
|
|
// Only convert if the call succeeded; RetVal will
|
|
// always contain the size whether the function
|
|
// succeeded or not
|
|
MultiByteToWideChar(g_acp, 0, lpDstAnsi, -1, lpDst, RetVal);
|
|
}
|
|
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=ExtractIconW
|
|
Begin=
|
|
HICON __stdcall
|
|
GodotExtractIconW( HINSTANCE hInst,
|
|
LPCWSTR lpszExeFileName,
|
|
UINT nIconIndex
|
|
)
|
|
{
|
|
LPSTR lpszExeFileNameAnsi;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lpszExeFileName, lpszExeFileNameAnsi);
|
|
|
|
return(ExtractIconA(hInst, lpszExeFileNameAnsi, nIconIndex));
|
|
}
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=ExtractIconExW
|
|
Begin=
|
|
UINT __stdcall
|
|
GodotExtractIconExW(LPCWSTR lpszFile, int nIconIndex, HICON * phiconLarge, HICON * phiconSmall, UINT nIcons)
|
|
{
|
|
LPSTR lpszFileAnsi;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lpszFile, lpszFileAnsi);
|
|
|
|
return(ExtractIconExA(lpszFileAnsi, nIconIndex, phiconLarge, phiconSmall, nIcons));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=ExtTextOutW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotExtTextOutW(HDC hdc, int X, int Y, UINT eto, const LPRECT lprc,
|
|
LPCWSTR lpString, UINT cbCount, const PINT lpDx)
|
|
{
|
|
// Obtained all logic here from Office's MsoExtTextOutW function. :-)
|
|
|
|
if ((!lpString) || (cbCount == 0))
|
|
{
|
|
char chT;
|
|
return ExtTextOutA(hdc, X, Y, eto, lprc, &chT, cbCount, lpDx);
|
|
}
|
|
|
|
// Optimize for all < 128 case
|
|
// CONSIDER: This code could likely be faster, couldn't it???
|
|
if (!(eto & ETO_GLYPH_INDEX) && cbCount < 256 && lpString[0] <= 127)
|
|
{
|
|
char lpchA[256];
|
|
register UINT ich;
|
|
BOOL fAscii = TRUE;
|
|
|
|
// Optimize for the pure ASCII case
|
|
for (ich = 0; ich < cbCount; ich++)
|
|
{
|
|
WCHAR wch = lpString[ich];
|
|
if ( wch <= 127 )
|
|
lpchA[ich] = (char) wch;
|
|
else
|
|
{
|
|
fAscii = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (fAscii)
|
|
return ExtTextOutA(hdc, X, Y, eto, lprc, lpchA, cbCount, lpDx);
|
|
}
|
|
|
|
// Call the 'W' version of the API, its safe now!
|
|
return ExtTextOutW(hdc, X, Y, eto, lprc, lpString, cbCount, lpDx);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=FillConsoleOutputCharacterW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotFillConsoleOutputCharacterW( HANDLE hConsoleOutput,
|
|
WCHAR cCharacter,
|
|
DWORD nLength,
|
|
COORD dwWriteCoord,
|
|
LPDWORD lpNumberOfCharsWritten
|
|
)
|
|
{
|
|
// Begin locals
|
|
char * cCharacterAnsi[2];
|
|
|
|
WideCharToMultiByte(g_oemcp, 0, (LPWSTR)&cCharacter, 1, (LPSTR)&cCharacterAnsi, 2, NULL, NULL);
|
|
|
|
// Call the 'A' version of the API
|
|
return(FillConsoleOutputCharacterA(hConsoleOutput,
|
|
*cCharacterAnsi[0],
|
|
nLength,
|
|
dwWriteCoord,
|
|
lpNumberOfCharsWritten
|
|
));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=FindExecutableW
|
|
Begin=
|
|
HINSTANCE __stdcall
|
|
GodotFindExecutableW(LPCWSTR lpFile, LPCWSTR lpDirectory, LPWSTR lpResult)
|
|
{
|
|
// UNSUPPORTED FUNCTION: Documented as a failure stub
|
|
char lpResultAnsi[MAX_PATH + 1];
|
|
LPSTR lpFileAnsi, lpDirectoryAnsi;
|
|
HINSTANCE RetVal;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lpFile, lpFileAnsi);
|
|
GODOT_TO_ACP_STACKALLOC(lpDirectory, lpDirectoryAnsi);
|
|
if((!lpFileAnsi && lpFile) ||
|
|
(!lpDirectoryAnsi && lpDirectory))
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
RetVal = FindExecutableA(lpFileAnsi, lpDirectoryAnsi, lpResultAnsi);
|
|
if(lpResult)
|
|
{
|
|
if(RetVal)
|
|
MultiByteToWideChar(g_acp, 0, lpResultAnsi, -1, lpResult, MAX_PATH);
|
|
else
|
|
*lpResult = L'\0';
|
|
}
|
|
|
|
return(RetVal);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=FindFirstChangeNotificationW
|
|
Begin=
|
|
HANDLE __stdcall
|
|
GodotFindFirstChangeNotificationW(LPCWSTR lpPathName, BOOL bWatchSubtree, DWORD dwNotifyFilter)
|
|
{
|
|
// Begin locals
|
|
LPSTR lpPathNameAnsi;
|
|
|
|
// Begin precall
|
|
GODOT_TO_CPG_STACKALLOC(lpPathName, lpPathNameAnsi, FILES_CPG, g_mcs);
|
|
if(lpPathNameAnsi==NULL)
|
|
{
|
|
return(INVALID_HANDLE_VALUE);
|
|
}
|
|
|
|
return(FindFirstChangeNotificationA(lpPathNameAnsi, bWatchSubtree, dwNotifyFilter));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=FindFirstFileW
|
|
Begin=
|
|
// We need an alternate "default" char when looking for file names, because the
|
|
// usual "?" is a valid wildcard character. For other file handling functions,
|
|
// the "?" is illegal so we can leave the call alone and let the API itself
|
|
// throw the error and call SetLastError.
|
|
const char c_szAltDefaultChar[] = "<";
|
|
|
|
HANDLE __stdcall
|
|
GodotFindFirstFileW(LPCWSTR lpFileName, LPWIN32_FIND_DATAW lpFindFileData)
|
|
{
|
|
// Begin locals
|
|
HANDLE RetVal;
|
|
LPSTR lpFileNameAnsi;
|
|
size_t lpFileNameLength;
|
|
WIN32_FIND_DATAA ffda;
|
|
|
|
// Begin precall
|
|
ZeroMemory(&ffda, sizeof(WIN32_FIND_DATAA));
|
|
if (FSTRING_VALID(lpFileName))
|
|
{
|
|
lpFileNameLength = gwcslen(lpFileName)+1;
|
|
_STACKALLOC(lpFileNameLength*g_mcs, lpFileNameAnsi);
|
|
if(lpFileNameAnsi==NULL)
|
|
{
|
|
return(0);
|
|
}
|
|
WideCharToMultiByte(FILES_CPG,
|
|
WC_DEFAULTCHAR|WC_COMPOSITECHECK, // enable default char handling
|
|
lpFileName,
|
|
lpFileNameLength,
|
|
lpFileNameAnsi,
|
|
lpFileNameLength*g_mcs,
|
|
c_szAltDefaultChar,
|
|
NULL);
|
|
}
|
|
else
|
|
lpFileNameAnsi = (LPSTR)lpFileName;
|
|
|
|
RetVal=FindFirstFileA(lpFileNameAnsi, &ffda);
|
|
|
|
if(RetVal != INVALID_HANDLE_VALUE)
|
|
Win32FindDataWfromA(lpFindFileData, &ffda);
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=FindNextFileW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotFindNextFileW(HANDLE hFindFile, LPWIN32_FIND_DATAW lpFindFileData)
|
|
{
|
|
// Begin locals
|
|
BOOL RetVal;
|
|
WIN32_FIND_DATAA ffda;
|
|
|
|
// Call the 'A' version of the API
|
|
ZeroMemory(&ffda, sizeof(WIN32_FIND_DATAA));
|
|
RetVal=FindNextFileA(hFindFile, &ffda);
|
|
|
|
// Begin postcall
|
|
if(RetVal)
|
|
Win32FindDataWfromA(lpFindFileData, &ffda);
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=FindResourceW
|
|
Begin=
|
|
HRSRC __stdcall
|
|
GodotFindResourceW(HMODULE hModule, LPCWSTR lpName, LPCWSTR lpType)
|
|
{
|
|
// We must wrap this function, see GodotFindResourceExW for more info.
|
|
// Just call through to GodotFindResourceExW with 0 for the language,
|
|
// anyway (which is all the Win9x code does).
|
|
return GodotFindResourceExW(hModule, lpType, lpName, 0);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=FindResourceExW
|
|
Begin=
|
|
HRSRC __stdcall
|
|
GodotFindResourceExW(HMODULE hModule, LPCWSTR lpType, LPCWSTR lpName, WORD wLanguage)
|
|
{
|
|
// We must wrap this function, even though it works on Win9x as
|
|
// Unicode, due to OSR v 4.1 bug # 92854. They were always calling
|
|
// LocalFree without alloc'ing, which corrupts the heap.
|
|
if (FWIN95_OR_98())
|
|
{
|
|
// Copy the params to stack variables. Win95/Win98 will fail in
|
|
// their call to LocalFree, but they ignore failure in teardown.
|
|
LPWSTR lpTypeC, lpNameC;
|
|
HRSRC RetVal;
|
|
|
|
if(FSTRING_VALID(lpType))
|
|
{
|
|
_STACKALLOC((gwcslen(lpType) + 1) * sizeof(WCHAR), lpTypeC);
|
|
if(lpTypeC==NULL)
|
|
{
|
|
return(0);
|
|
}
|
|
gwcscpy(lpTypeC, lpType);
|
|
}
|
|
else
|
|
lpTypeC = (LPWSTR)lpType;
|
|
|
|
if(FSTRING_VALID(lpName))
|
|
{
|
|
_STACKALLOC((gwcslen(lpName) + 1) * sizeof(WCHAR), lpNameC);
|
|
if(lpNameC==NULL)
|
|
{
|
|
return(0);
|
|
}
|
|
gwcscpy(lpNameC, lpName);
|
|
}
|
|
else
|
|
lpNameC = (LPWSTR)lpName;
|
|
|
|
RetVal = FindResourceExW(hModule, lpTypeC, lpNameC, wLanguage);
|
|
|
|
// If the last error is invalid handle but the function succeeded, then lets
|
|
// assume it came from the bogus LocalFree call and clear things out here.
|
|
if ((RetVal != 0) && (GetLastError() == ERROR_INVALID_HANDLE))
|
|
SetLastError(ERROR_SUCCESS);
|
|
|
|
return (RetVal);
|
|
}
|
|
|
|
// WinME case
|
|
return FindResourceExW(hModule, lpType, lpName, wLanguage);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=FindTextW
|
|
Begin=
|
|
HWND __stdcall
|
|
GodotFindTextW(LPFINDREPLACEW lpfr)
|
|
{
|
|
return(FindReplaceTextHelper(lpfr, TRUE));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=FindWindowW
|
|
Begin=
|
|
HWND __stdcall
|
|
GodotFindWindowW(LPCWSTR lpszClass, LPCWSTR lpszWindow)
|
|
{
|
|
LPSTR lpszClassAnsi, lpszWindowAnsi;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lpszClass, lpszClassAnsi);
|
|
GODOT_TO_ACP_STACKALLOC(lpszWindow, lpszWindowAnsi);
|
|
if((!lpszClassAnsi && lpszClass) ||
|
|
(!lpszWindowAnsi && lpszWindow))
|
|
return(0);
|
|
|
|
return(FindWindowA(lpszClassAnsi, lpszWindowAnsi));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=FindWindowExW
|
|
Begin=
|
|
HWND __stdcall
|
|
GodotFindWindowExW(HWND hwndParent, HWND hwndChildAfter, LPCWSTR lpszClass, LPCWSTR lpszWindow)
|
|
{
|
|
LPSTR lpszClassAnsi, lpszWindowAnsi;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lpszClass, lpszClassAnsi);
|
|
GODOT_TO_ACP_STACKALLOC(lpszWindow, lpszWindowAnsi);
|
|
if((!lpszClassAnsi && lpszClass) ||
|
|
(!lpszWindowAnsi && lpszWindow))
|
|
return(0);
|
|
|
|
return(FindWindowExA(hwndParent, hwndChildAfter, lpszClassAnsi, lpszWindowAnsi));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=FormatMessageW
|
|
Begin=
|
|
|
|
DWORD __stdcall
|
|
GodotFormatMessageW(DWORD dwFlags, LPCVOID lpSource, DWORD dwMsgId,
|
|
DWORD dwLangId, LPWSTR lpBuffer, DWORD nSize,
|
|
va_list * Args)
|
|
{
|
|
LPSTR lpSourceA; // "A" wrapper for lpSource
|
|
va_list * ArgsA; // "A" wrapper for Args
|
|
DWORD RetVal; // the return value
|
|
LPSTR szBuffer; // "A" wrapper for lpBuffer
|
|
UINT cpg; // code page for the conversions, if any
|
|
UINT mcs; // max bytes per character
|
|
LPSTR szScratch = NULL; // Our scratchpad buffer that we keep our strings in
|
|
|
|
BOOL fAllocBuffer = (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER);
|
|
|
|
// Take care of code page issues, and handle lpSource
|
|
if (dwFlags & FORMAT_MESSAGE_FROM_STRING)
|
|
{
|
|
cpg = g_acp;
|
|
mcs = g_mcs;
|
|
GODOT_TO_ACP_STACKALLOC(lpSource, lpSourceA);
|
|
}
|
|
else
|
|
{
|
|
cpg = CpgFromLocale(dwLangId);
|
|
mcs = CbPerChOfCpg(cpg);
|
|
lpSourceA = (LPSTR)lpSource;
|
|
}
|
|
|
|
// First lets take care of Args, if we need to
|
|
if((Args == NULL) || (dwFlags & FORMAT_MESSAGE_IGNORE_INSERTS))
|
|
{
|
|
// They passed in no args, so lets give them no Args!
|
|
ArgsA = NULL;
|
|
szScratch = NULL;
|
|
}
|
|
else
|
|
{
|
|
PVOID pBuffer = NULL;
|
|
|
|
// Ok, what we have to do here is call FormatMessage and ignore
|
|
// inserts so we can get the unformatted string. We will use it
|
|
// later to get arg counts and find out which args are strings.
|
|
RetVal = FormatMessageA((dwFlags | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER),
|
|
lpSourceA,
|
|
dwMsgId,
|
|
dwLangId,
|
|
(char*)&pBuffer,
|
|
nSize,
|
|
NULL);
|
|
if(RetVal == 0)
|
|
{
|
|
// We did not even make it THIS far; lets give up
|
|
return(0);
|
|
}
|
|
else
|
|
{
|
|
UINT rgConv[MAXINSERTS];
|
|
LPSTR pch;
|
|
UINT cItems = 0;
|
|
UINT cStrings = 0;
|
|
|
|
// Init the shadow array: this way any inserts not
|
|
// included will default to non-string parameters
|
|
ZeroMemory(rgConv, (sizeof(UINT) * (MAXINSERTS)));
|
|
|
|
// Ok, pBuffer points to the string. Use it, filling rgbString so we know
|
|
// whether each param is a string or not, and also so we know the count
|
|
for (pch = (LPSTR)pBuffer; *pch; pch++)
|
|
{
|
|
CHAR szNum[2];
|
|
UINT iNum;
|
|
|
|
if (*pch == L'%')
|
|
{
|
|
pch++;
|
|
// Found an insertion. Get the digit or two.
|
|
if (*pch == '0')
|
|
continue; // "%0" is special
|
|
|
|
if (*pch < '0' || *pch > '9')
|
|
{
|
|
// skip % followed by nondigit
|
|
continue;
|
|
}
|
|
|
|
szNum[0] = '\0';
|
|
szNum[1] = '\0';
|
|
|
|
// Move one past the digit we just detected
|
|
pch++;
|
|
if (*pch >= '0' && *pch <= '9')
|
|
{
|
|
// Move one past the optional second digit we just
|
|
// detected and lets make those two digits a number
|
|
pch++;
|
|
memcpy(szNum, pch - 2, (sizeof(CHAR) * 2));
|
|
iNum = MiniAtoI(szNum);
|
|
}
|
|
else
|
|
{
|
|
// Its not a digit, so we will just make that one
|
|
// string 'digit' a number
|
|
memcpy(szNum, pch - 1, sizeof(CHAR));
|
|
iNum = MiniAtoI(szNum);
|
|
}
|
|
|
|
// We must allow for the fact that there may be more insert
|
|
// tokens then actual inserts. Thus, cItems is no mere count
|
|
// of items, it is a count of possible items? (see Windows
|
|
// Bugs #368881 for details).
|
|
if(cItems < iNum)
|
|
cItems = iNum;
|
|
|
|
// See if there is a formatting character
|
|
if (*pch != '!')
|
|
{
|
|
// No optional type spec, so assume its a string
|
|
rgConv[iNum - 1]=1;
|
|
cStrings++;
|
|
|
|
if(*pch == '\0')
|
|
break;
|
|
// Make sure we do not skip the next character
|
|
// when the for loop increments us in a moment
|
|
pch--;
|
|
}
|
|
else
|
|
{
|
|
// See "printf Type Field Characters" for details on our support here.
|
|
// Note that e, E, f, G, and g are not supported by FormatMessage, so
|
|
// everything we care about is either an int, UINT, or string.
|
|
|
|
// Skip the exclamation point itself to get the formatting character
|
|
pch++;
|
|
switch(*pch)
|
|
{
|
|
case 'c':
|
|
case 'C':
|
|
case 's':
|
|
case 'S':
|
|
rgConv[iNum - 1]=1;
|
|
cStrings++;
|
|
break;
|
|
|
|
case 'd':
|
|
case 'i':
|
|
case 'u':
|
|
case 'o':
|
|
case 'x':
|
|
case 'X':
|
|
default:
|
|
rgConv[iNum - 1]=0;
|
|
break;
|
|
}
|
|
|
|
// Skip on past the formatting character (which ought
|
|
// to put us on the closing exclamation point).
|
|
pch++;
|
|
}
|
|
}
|
|
}
|
|
|
|
//free the buffer now
|
|
LocalFree(pBuffer);
|
|
|
|
if(cItems == 0)
|
|
{
|
|
// They passed in no args in their call even though
|
|
// they said they had some, so lets give them no Args.
|
|
ArgsA = NULL;
|
|
szScratch = NULL;
|
|
}
|
|
else
|
|
{
|
|
ULONG rgpInserts[MAXINSERTS]; // our own argument array of inserts
|
|
UINT idxInsert; // index of the insert we are working on
|
|
DWORD dwOffset = 0; // number of bytes used in rgszInsert
|
|
|
|
if(cStrings)
|
|
{
|
|
szScratch = GodotHeapAlloc(CCHMAXPERINSERT * cStrings);
|
|
if(szScratch == NULL)
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(0);
|
|
}
|
|
}
|
|
|
|
for (idxInsert = 0 ; idxInsert < cItems; idxInsert++)
|
|
{
|
|
LPWSTR lpwzT;
|
|
|
|
// If this is an arg array, than treat Args like an array of LPWSTRs
|
|
// and read the Args one at a time that way. Otherwise, use va_arg to
|
|
// pick off the next item.
|
|
if (dwFlags & FORMAT_MESSAGE_ARGUMENT_ARRAY)
|
|
lpwzT = (LPWSTR)Args[idxInsert];
|
|
else
|
|
lpwzT = va_arg(*Args, LPWSTR);
|
|
|
|
if(rgConv[idxInsert]==1)
|
|
{
|
|
// Convert strings W->A
|
|
UINT cbInsert = WideCharToMultiByte(cpg,
|
|
0,
|
|
lpwzT,
|
|
-1,
|
|
(LPSTR)(szScratch + dwOffset),
|
|
CCHMAXPERINSERT,
|
|
NULL,
|
|
NULL);
|
|
rgpInserts[idxInsert] = (ULONG)(LPSTR)(szScratch + dwOffset);
|
|
dwOffset += cbInsert;
|
|
}
|
|
else
|
|
{
|
|
// Copy the data, directly. No conversion needed (or even wanted)
|
|
rgpInserts[idxInsert] = (UINT)lpwzT;
|
|
}
|
|
}
|
|
// We have allocated (CCHMAXPERINSERT * cStrings) bytes of space but we only need
|
|
// dwOffset bytes. Lets shrink the buffer to give back as much space as we can.
|
|
if(dwOffset < CCHMAXPERINSERT)
|
|
szScratch = (LPSTR)GodotHeapReAlloc(szScratch, dwOffset+1);
|
|
|
|
// We are turning this into an argument array list, so set the flags that way
|
|
dwFlags |= FORMAT_MESSAGE_ARGUMENT_ARRAY;
|
|
ArgsA = (va_list *)rgpInserts;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (fAllocBuffer)
|
|
{
|
|
// Must pass address of szBuffer so the API can fill it in. We will
|
|
// then copy it to our own LocalAlloc'ed buffer and free the OS one.
|
|
szBuffer = NULL;
|
|
RetVal=FormatMessageA(dwFlags,
|
|
lpSourceA,
|
|
dwMsgId,
|
|
dwLangId,
|
|
(char*)&szBuffer,
|
|
(mcs * nSize),
|
|
ArgsA);
|
|
}
|
|
else
|
|
{
|
|
// Must alloc szBuffer ourselves
|
|
_STACKALLOC((mcs * nSize), szBuffer);
|
|
if(szBuffer==NULL)
|
|
{
|
|
if(szScratch)
|
|
GodotHeapFree(szScratch);
|
|
|
|
// The API will have changed the last error; reset
|
|
// it to the stack overflow so they will know why
|
|
// we failed
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(FALSE);
|
|
}
|
|
RetVal=FormatMessageA(dwFlags,
|
|
lpSourceA,
|
|
dwMsgId,
|
|
dwLangId,
|
|
szBuffer,
|
|
(mcs * nSize),
|
|
ArgsA);
|
|
}
|
|
|
|
if (!RetVal)
|
|
{
|
|
if(fAllocBuffer)
|
|
{
|
|
lpBuffer = NULL;
|
|
}
|
|
else
|
|
{
|
|
if (FSTRING_VALID(lpBuffer) && (0 < nSize))
|
|
*lpBuffer = L'\0';
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (fAllocBuffer)
|
|
{
|
|
// szBuffer contains a LocalAlloc'ed ptr to new string. lpBuffer is a
|
|
// WCHAR** when FORMAT_MESSAGE_ALLOCATE_BUFFER is defined. To act like
|
|
// the API, we LocalAlloc our own buffer for the caller.
|
|
WCHAR* lpBufferT = (WCHAR*)LocalAlloc(NONZEROLPTR, (RetVal + 1) * sizeof(WCHAR));
|
|
if(lpBufferT == NULL)
|
|
RetVal = 0;
|
|
else
|
|
{
|
|
if(RetVal = MultiByteToWideChar(g_acp, 0, szBuffer, -1, lpBufferT, RetVal+1))
|
|
RetVal--;
|
|
lpBufferT[RetVal] = L'\0';
|
|
*(WCHAR**)lpBuffer = lpBufferT;
|
|
}
|
|
|
|
// free up the buffer the OS created, since we created our own for the user.
|
|
LocalFree(szBuffer);
|
|
}
|
|
else
|
|
{
|
|
// Just convert
|
|
RetVal = MultiByteToWideChar(cpg, 0, szBuffer, RetVal, lpBuffer, nSize);
|
|
lpBuffer[RetVal] = L'\0';
|
|
}
|
|
|
|
}
|
|
|
|
if(szScratch)
|
|
GodotHeapFree(szScratch);
|
|
return(RetVal);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=FreeContextBuffer
|
|
Begin=
|
|
SECURITY_STATUS __stdcall GodotFreeContextBuffer(void * pvContextBuffer)
|
|
{
|
|
// ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
|
|
return(FreeContextBuffer(pvContextBuffer));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=FreeEnvironmentStringsW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotFreeEnvironmentStringsW(LPWSTR lpszEnvironmentBlock)
|
|
{
|
|
// Call the free function directly: we cannot thunk since we
|
|
// freed THAT buffer which the OS gave us, long ago.
|
|
// See comments under GodotGetEnvironmentStringsW for details.
|
|
return(GodotHeapFree(lpszEnvironmentBlock));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetAltTabInfoW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotGetAltTabInfoW(HWND hwnd, int iItem, PALTTABINFO pati, LPWSTR pszItemText, UINT cchItemText)
|
|
{
|
|
// Begin locals
|
|
BOOL RetVal = FALSE;
|
|
|
|
if (s_pfnGetAltTabInfoA == NULL)
|
|
{
|
|
// Must allocate stuff for this API call
|
|
s_pfnGetAltTabInfoA = (PFNgatia)GetUserProc("GetAltTabInfoA");
|
|
}
|
|
|
|
if (s_pfnGetAltTabInfoA)
|
|
{
|
|
LPSTR pszItemTextAnsi;
|
|
|
|
_STACKALLOC((cchItemText*g_mcs)+1, pszItemTextAnsi);
|
|
if(pszItemTextAnsi==NULL)
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
RetVal = (s_pfnGetAltTabInfoA(hwnd, iItem, pati, pszItemTextAnsi, cchItemText));
|
|
|
|
// Begin postcall
|
|
if (RetVal && (pszItemText != NULL))
|
|
MultiByteToWideChar(g_acp, 0, pszItemTextAnsi, -1, pszItemText, gwcslen(pszItemText));
|
|
}
|
|
else
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetAtomNameW
|
|
Begin=
|
|
UINT __stdcall
|
|
GodotGetAtomNameW(ATOM nAtom, LPWSTR lpBuffer, int nSize)
|
|
{
|
|
// Begin locals
|
|
UINT RetVal;
|
|
LPSTR lpBufferAnsi;
|
|
|
|
_STACKALLOC((nSize*g_mcs)+1, lpBufferAnsi);
|
|
if(lpBufferAnsi==NULL)
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
// Call the 'A' version of the API
|
|
RetVal=GetAtomNameA(nAtom, lpBufferAnsi, nSize);
|
|
|
|
// Begin postcall
|
|
if (RetVal)
|
|
MultiByteToWideChar(g_acp, 0, lpBufferAnsi, -1, lpBuffer, nSize);
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetCalendarInfoW
|
|
Begin=
|
|
int __stdcall
|
|
GodotGetCalendarInfoW( LCID Locale,
|
|
CALID Calendar,
|
|
CALTYPE CalType,
|
|
LPWSTR lpCalData,
|
|
int cchData,
|
|
LPDWORD lpValue
|
|
)
|
|
{
|
|
// Begin locals
|
|
int RetVal = 0;
|
|
LPSTR lpCalDataAnsi;
|
|
UINT cpg;
|
|
UINT mcs;
|
|
|
|
if (s_pfnGetCalendarInfoA == NULL)
|
|
{
|
|
// Must allocate stuff for this API call
|
|
s_pfnGetCalendarInfoA = (PFNgcia)GetKernelProc("GetCalendarInfoA");
|
|
}
|
|
|
|
if (s_pfnGetCalendarInfoA)
|
|
{
|
|
if(CalType & CAL_USE_CP_ACP)
|
|
{
|
|
cpg = g_acp;
|
|
mcs = g_mcs;
|
|
}
|
|
else
|
|
{
|
|
cpg = CpgFromLocale(Locale);
|
|
mcs = CbPerChOfCpg(cpg);
|
|
}
|
|
|
|
_STACKALLOC((cchData+1)*mcs, lpCalDataAnsi);
|
|
RetVal = (s_pfnGetCalendarInfoA (Locale,
|
|
Calendar,
|
|
CalType,
|
|
lpCalDataAnsi,
|
|
(cchData*mcs), // We can be optimists, we allocated for it!
|
|
lpValue));
|
|
|
|
// Begin postcall
|
|
if (lpCalDataAnsi != 0)
|
|
MultiByteToWideChar(cpg, 0, lpCalDataAnsi, cchData*mcs, lpCalData, cchData);
|
|
}
|
|
else
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetCharABCWidthsW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotGetCharABCWidthsW(HDC hdc, UINT ichFirst, UINT ichLast, LPABC lpabc)
|
|
{
|
|
BOOL RetVal = FALSE;
|
|
UINT ich;
|
|
CHAR * sz[2];
|
|
UINT cpg = CpgFromHdc(hdc);
|
|
UINT mcs = CbPerChOfCpg(cpg);
|
|
|
|
// Do some basic param validation
|
|
if((ichLast < ichFirst) || (!lpabc))
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return(FALSE);
|
|
}
|
|
|
|
for (ich = ichFirst ; ich < ichLast ; ich++)
|
|
{
|
|
// Convert each character and call the API, one at a time. This might kind
|
|
// of suck, perf-wise, but its the best we can do if we want to be able to
|
|
// give them the values they expect from the API.
|
|
sz[0] = '\0';
|
|
sz[1] = '\0';
|
|
WideCharToMultiByte(cpg, 0, (WCHAR *)ich, 1, (LPSTR)&sz, mcs, NULL, NULL);
|
|
RetVal = GetCharABCWidthsA(hdc, ich, ich, &lpabc[ich - ichFirst]);
|
|
|
|
if(!RetVal)
|
|
{
|
|
// The function failed, so bail
|
|
break;
|
|
}
|
|
}
|
|
return(RetVal);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetCharABCWidthsFloatW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotGetCharABCWidthsFloatW(HDC hdc, UINT ichFirst, UINT ichLast, LPABCFLOAT lpABCF)
|
|
{
|
|
BOOL RetVal = FALSE;
|
|
UINT ich;
|
|
CHAR * sz[2];
|
|
UINT cpg = CpgFromHdc(hdc);
|
|
UINT mcs = CbPerChOfCpg(cpg);
|
|
|
|
// Do some basic param validation
|
|
if((ichLast < ichFirst) || (!lpABCF))
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return(FALSE);
|
|
}
|
|
|
|
for (ich = ichFirst ; ich < ichLast ; ich++)
|
|
{
|
|
// Convert each character and call the API, one at a time. This might kind
|
|
// of suck, perf-wise, but its the best we can do if we want to be able to
|
|
// give them the values they expect from the API.
|
|
sz[0] = '\0';
|
|
sz[1] = '\0';
|
|
WideCharToMultiByte(cpg, 0, (WCHAR *)ich, 1, (LPSTR)&sz, mcs, NULL, NULL);
|
|
RetVal = GetCharABCWidthsFloatA(hdc, ich, ich, &lpABCF[ich - ichFirst]);
|
|
|
|
if(!RetVal)
|
|
{
|
|
// The function failed, so bail
|
|
break;
|
|
}
|
|
}
|
|
return(RetVal);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetCharWidthW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotGetCharWidthW(HDC hdc, UINT iFirstChar, UINT iLastChar, LPINT lpBuffer)
|
|
{
|
|
// Due to a bug (feature?) in Win95, characters in Symbol/Wingding/other
|
|
// fonts map to 0xf000, while in NT they map to chars in the default
|
|
// codepage. We cannot really change the NT behavior and who would want to
|
|
// change the Win9x behavior, anyway? Too complicated!
|
|
if (iLastChar <= 127)
|
|
{
|
|
if (GetCharWidthA(hdc, iFirstChar, iLastChar, lpBuffer))
|
|
return TRUE;
|
|
}
|
|
|
|
// Call the 'W' version of the API here, since it is available
|
|
return(GetCharWidthW(hdc, iFirstChar, iLastChar, lpBuffer));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetCharWidthFloatW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotGetCharWidthFloatW(HDC hdc, UINT ichFirst, UINT ichLast, PFLOAT pxBuffer)
|
|
{
|
|
BOOL RetVal = FALSE;
|
|
UINT ich;
|
|
CHAR * sz[2];
|
|
UINT cpg = CpgFromHdc(hdc);
|
|
UINT mcs = CbPerChOfCpg(cpg);
|
|
|
|
// Do some basic param validation
|
|
if((ichLast < ichFirst) || (!pxBuffer))
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return(FALSE);
|
|
}
|
|
|
|
for (ich = ichFirst ; ich < ichLast ; ich++)
|
|
{
|
|
// Convert each character and call the API, one at a time. This might kind
|
|
// of suck, perf-wise, but its the best we can do if we want to be able to
|
|
// give them the values they expect from the API.
|
|
sz[0] = '\0';
|
|
sz[1] = '\0';
|
|
WideCharToMultiByte(cpg, 0, (WCHAR *)ich, 1, (LPSTR)&sz, mcs, NULL, NULL);
|
|
RetVal = GetCharWidthFloatA(hdc, ich, ich, &pxBuffer[ich - ichFirst]);
|
|
|
|
if(!RetVal)
|
|
{
|
|
// The function failed, so bail
|
|
break;
|
|
}
|
|
}
|
|
return(RetVal);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetClassInfoW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotGetClassInfoW(HINSTANCE hInstance, LPCWSTR lpClassName, LPWNDCLASSW lpwc)
|
|
{
|
|
// Begin locals
|
|
BOOL RetVal;
|
|
LPSTR lpClassNameAnsi;
|
|
WNDCLASSA wca;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lpClassName, lpClassNameAnsi);
|
|
if(!lpClassNameAnsi && lpClassName)
|
|
return(FALSE);
|
|
|
|
ZeroMemory(&wca, sizeof(WNDCLASSA));
|
|
|
|
RetVal=GetClassInfoA(hInstance, lpClassNameAnsi, &wca);
|
|
|
|
// Begin postcall
|
|
if(RetVal)
|
|
{
|
|
memcpy(lpwc, &wca, sizeof(UINT)+sizeof(WNDPROC)+2*sizeof(int)+4*sizeof(HANDLE));
|
|
|
|
// See comments at the top of the file for why we are using a
|
|
// static buffer here for menu and class names
|
|
if (FSTRING_VALID(wca.lpszMenuName))
|
|
{
|
|
MultiByteToWideChar(g_acp, 0, wca.lpszMenuName, -1, m_wzMenuName, 256);
|
|
lpwc->lpszMenuName = m_wzMenuName;
|
|
}
|
|
else
|
|
lpwc->lpszMenuName = (LPWSTR)wca.lpszMenuName;
|
|
|
|
if (FSTRING_VALID(wca.lpszClassName))
|
|
{
|
|
MultiByteToWideChar(g_acp, 0, wca.lpszClassName, -1, m_wzClassName, 256);
|
|
lpwc->lpszClassName = m_wzClassName;
|
|
}
|
|
else
|
|
lpwc->lpszClassName = (LPWSTR)wca.lpszClassName;
|
|
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetClassInfoExW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotGetClassInfoExW(HINSTANCE hinst, LPCWSTR lpszClass, LPWNDCLASSEXW lpwce)
|
|
{
|
|
// Begin locals
|
|
BOOL RetVal;
|
|
LPSTR lpszClassAnsi;
|
|
WNDCLASSEXA wcea;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lpszClass, lpszClassAnsi);
|
|
if(!lpszClassAnsi && lpszClass)
|
|
return(FALSE);
|
|
|
|
ZeroMemory(&wcea, sizeof(WNDCLASSEXA));
|
|
wcea.cbSize = sizeof(WNDCLASSEXA);
|
|
RetVal=GetClassInfoExA(hinst, lpszClassAnsi, &wcea);
|
|
|
|
// Begin postcall
|
|
if(RetVal)
|
|
{
|
|
memcpy(&lpwce->style,
|
|
&wcea.style,
|
|
sizeof(UINT)+sizeof(WNDPROC)+(2*sizeof(int))+(4*sizeof(HANDLE)));
|
|
|
|
// See comments at the top of the file for why we are using a
|
|
// static buffer here
|
|
if (FSTRING_VALID(wcea.lpszMenuName))
|
|
{
|
|
MultiByteToWideChar(g_acp, 0, wcea.lpszMenuName, -1, m_wzMenuName, 256);
|
|
lpwce->lpszMenuName = m_wzMenuName;
|
|
}
|
|
else
|
|
lpwce->lpszMenuName = (LPWSTR)wcea.lpszMenuName;
|
|
|
|
if (FSTRING_VALID(wcea.lpszClassName))
|
|
{
|
|
MultiByteToWideChar(g_acp, 0, wcea.lpszClassName, -1, m_wzClassName, 256);
|
|
lpwce->lpszClassName = m_wzClassName;
|
|
}
|
|
else
|
|
lpwce->lpszClassName = (LPWSTR)wcea.lpszClassName;
|
|
lpwce->hIconSm = wcea.hIconSm;
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetClassLongW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotGetClassLongW(HWND hWnd, int nIndex)
|
|
{
|
|
// Begin locals
|
|
DWORD RetVal;
|
|
|
|
RetVal=GetClassLongA(hWnd, nIndex);
|
|
|
|
if((RetVal != 0) && (nIndex == GCL_MENUNAME))
|
|
{
|
|
// We need to convert this string to Unicode and stick it in
|
|
// our global buffer, then return the pointer to that buffer.
|
|
// See comments at the dec. of g_szMenuName for why things
|
|
// have to be done this way.
|
|
MultiByteToWideChar(g_acp, 0, (LPSTR)RetVal, -1, m_wzMenuName, 256);
|
|
RetVal = (DWORD)m_wzMenuName;
|
|
}
|
|
|
|
return(RetVal);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetClassNameW
|
|
Begin=
|
|
int __stdcall
|
|
GodotGetClassNameW(HWND hWnd, LPWSTR lpClassName, int nMaxCount)
|
|
{
|
|
// Begin locals
|
|
int RetVal;
|
|
LPSTR lpClassNameAnsi;
|
|
|
|
_STACKALLOC((nMaxCount*g_mcs)+1, lpClassNameAnsi);
|
|
if(lpClassNameAnsi == NULL)
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
// Call the 'A' version of the API
|
|
RetVal=GetClassNameA(hWnd, lpClassNameAnsi, nMaxCount);
|
|
|
|
// Begin postcall
|
|
if ((RetVal) && (nMaxCount > 0))
|
|
MultiByteToWideChar(g_acp, 0, lpClassNameAnsi, -1, lpClassName, nMaxCount);
|
|
else
|
|
{
|
|
if (lpClassName && 0 < nMaxCount)
|
|
*lpClassName = L'\0';
|
|
}
|
|
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetClipboardData
|
|
Begin=
|
|
HANDLE __stdcall
|
|
GodotGetClipboardData(UINT uFormat)
|
|
{
|
|
HANDLE RetVal = GetClipboardData(uFormat);
|
|
|
|
if(RetVal==NULL)
|
|
{
|
|
if((!IsClipboardFormatAvailable(uFormat)) &&
|
|
(GodotIsClipboardFormatAvailable(uFormat)))
|
|
{
|
|
// System says it is not available, but we know better!
|
|
|
|
BOOL fUnicodeOnClipboard;
|
|
HANDLE hMemOnClipboard;
|
|
|
|
fUnicodeOnClipboard = (uFormat != CF_UNICODETEXT);
|
|
hMemOnClipboard = GetClipboardData(((!fUnicodeOnClipboard) ? CF_TEXT : CF_UNICODETEXT));
|
|
if(hMemOnClipboard != 0)
|
|
{
|
|
// We have a handle to the data, now lets use it.
|
|
PULONG pMemOnClipboard;;
|
|
if(pMemOnClipboard = GlobalLock(hMemOnClipboard))
|
|
{
|
|
HANDLE hLocale = GetClipboardData(CF_LOCALE);
|
|
UINT cpg;
|
|
UINT mcs;
|
|
size_t cb;
|
|
HANDLE hMemSynthetic;
|
|
|
|
// Figure out the code page to use now -- this is where we care whether
|
|
// the caller wanted CF_TEXT vs. CF_OEMTEXT -- since it determines
|
|
// whether we want ACP or OEMCP.
|
|
// If they want Unicode then we can grab either one (Win9x supports
|
|
// synthetic conversions CF_TEXT <---> CF_OEMTEXT) so we choose CF_TEXT.
|
|
if(fUnicodeOnClipboard && (uFormat==CF_OEMTEXT))
|
|
cpg = (hLocale ? (CpgOemFromLocale((LCID)(&hLocale))) : g_oemcp);
|
|
else
|
|
cpg = (hLocale ? (CpgFromLocale((LCID)(&hLocale))) : g_acp);
|
|
mcs = CbPerChOfCpg(cpg);
|
|
|
|
// Get the appropriate buffer size, based on the existing format and the
|
|
// size of the actual data. This may be bigger than we need it to be if
|
|
// the cpg is a DBCS code page.
|
|
if(fUnicodeOnClipboard)
|
|
cb = gwcslen((LPWSTR)pMemOnClipboard) * mcs;
|
|
else
|
|
cb = lstrlenA((LPSTR)pMemOnClipboard) * sizeof(WCHAR);
|
|
|
|
// Allocate some memory for the converted string and then lock it
|
|
if(hMemSynthetic = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, cb))
|
|
{
|
|
PULONG pMemSynthetic = GlobalLock(hMemSynthetic);
|
|
|
|
if(pMemSynthetic == NULL)
|
|
{
|
|
// Lock failed, no need to go further, lets bail.
|
|
GlobalFree(hMemSynthetic);
|
|
}
|
|
else
|
|
{
|
|
if(fUnicodeOnClipboard)
|
|
{
|
|
WideCharToMultiByte(cpg,
|
|
0,
|
|
(LPWSTR)pMemOnClipboard,
|
|
-1,
|
|
(LPSTR)pMemSynthetic,
|
|
cb,
|
|
NULL,
|
|
NULL);
|
|
}
|
|
else
|
|
{
|
|
MultiByteToWideChar(cpg,
|
|
0,
|
|
(LPSTR)pMemOnClipboard,
|
|
-1,
|
|
(LPWSTR)pMemSynthetic,
|
|
(cb / sizeof(WCHAR)));
|
|
}
|
|
|
|
// We made it this far, we will now stick the data on the
|
|
// clipboard. The function thankfully returns the handle
|
|
// to the clipboard object that has just been set. Which is
|
|
// just what the caller wants!
|
|
|
|
// CONSIDER: Call GlobalReAlloc when FDBCS_CPG(cpg)? In that
|
|
// case, the buffer may be larger than it has to be.
|
|
RetVal = SetClipboardData(uFormat, pMemSynthetic);
|
|
|
|
GlobalUnlock(hMemSynthetic);
|
|
}
|
|
}
|
|
GlobalUnlock(hMemOnClipboard);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return(RetVal);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetClipboardFormatNameW
|
|
Begin=
|
|
int __stdcall
|
|
GodotGetClipboardFormatNameW(UINT format, LPWSTR lpszFormatName, int cchMaxCount)
|
|
{
|
|
// Begin locals
|
|
int RetVal;
|
|
LPSTR lpszFormatNameAnsi;
|
|
|
|
_STACKALLOC((cchMaxCount*g_mcs)+1, lpszFormatNameAnsi);
|
|
if(lpszFormatNameAnsi==NULL)
|
|
{
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(0);
|
|
}
|
|
ZeroMemory(lpszFormatNameAnsi, (cchMaxCount*g_mcs)+1);
|
|
|
|
RetVal=GetClipboardFormatNameA(format, lpszFormatNameAnsi, cchMaxCount);
|
|
|
|
// Begin postcall
|
|
if(RetVal)
|
|
MultiByteToWideChar(g_acp, 0, lpszFormatNameAnsi, -1, lpszFormatName, cchMaxCount);
|
|
else
|
|
*lpszFormatName = L'\0';
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetComputerNameW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotGetComputerNameW(LPWSTR lpBuffer, LPDWORD nSize)
|
|
{
|
|
BOOL RetVal;
|
|
LPSTR lpBufferAnsi;
|
|
WCHAR wzBuffer[MAX_COMPUTERNAME_LENGTH + 1];
|
|
DWORD nSizeT = MAX_COMPUTERNAME_LENGTH + 1;
|
|
|
|
|
|
// We will get the full string, always. Win9x is documented as
|
|
// failing if the input size is less than MAX_COMPUTERNAME_LENGTH + 1.
|
|
_STACKALLOC((nSizeT * g_mcs) + 1, lpBufferAnsi);
|
|
if(lpBufferAnsi==NULL)
|
|
{
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(0);
|
|
}
|
|
ZeroMemory(lpBufferAnsi, (nSizeT * g_mcs) + 1);
|
|
ZeroMemory(wzBuffer, nSizeT * sizeof(WCHAR));
|
|
|
|
RetVal=GetComputerNameA(lpBufferAnsi, &nSizeT);
|
|
|
|
// Begin postcall
|
|
if(RetVal)
|
|
{
|
|
MultiByteToWideChar(g_acp,
|
|
0,
|
|
lpBufferAnsi,
|
|
nSizeT + 1,
|
|
wzBuffer,
|
|
MAX_COMPUTERNAME_LENGTH);
|
|
if(*nSize >= nSizeT)
|
|
{
|
|
// Their buffer is big enough, so copy it over
|
|
gwcscpy(lpBuffer, wzBuffer);
|
|
*nSize = gwcslen(wzBuffer);
|
|
}
|
|
else
|
|
{
|
|
// The A call succeeded, but we need to make it fail
|
|
// since they did not give us enough buffer. So act
|
|
// like the API does and return the size plus the null
|
|
*nSize = gwcslen(wzBuffer) + 1;
|
|
RetVal = 0;
|
|
SetLastError(ERROR_BUFFER_OVERFLOW);
|
|
}
|
|
}
|
|
else
|
|
*lpBuffer = L'0';
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetConsoleTitleW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotGetConsoleTitleW(LPWSTR lpConsoleTitle, DWORD nSize)
|
|
{
|
|
// Begin locals
|
|
DWORD RetVal;
|
|
LPSTR lpConsoleTitleAnsi;
|
|
|
|
_STACKALLOC((nSize*g_mcs)+1, lpConsoleTitleAnsi);
|
|
if(lpConsoleTitleAnsi==NULL)
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
RetVal=GetConsoleTitleA(lpConsoleTitleAnsi, nSize);
|
|
|
|
// Begin postcall
|
|
if(RetVal && lpConsoleTitle)
|
|
MultiByteToWideChar(g_oemcp, 0, lpConsoleTitleAnsi, -1, lpConsoleTitle, nSize);
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetCPInfo
|
|
Begin=
|
|
// GetCPInfo is wrapped for UTF-7/UTF-8 support
|
|
BOOL __stdcall
|
|
GodotGetCPInfo(UINT CodePage, LPCPINFO lpCPInfo)
|
|
{
|
|
// See if it's a special code page value for UTF translations.
|
|
if (CodePage >= NLS_CP_ALGORITHM_RANGE)
|
|
return (UTFCPInfo(CodePage, lpCPInfo, FALSE));
|
|
|
|
if (CodePage == CP_GB18030)
|
|
return (GB18030Helper(CodePage, NLS_CP_CPINFO, NULL, 0, NULL, 0, lpCPInfo));
|
|
|
|
return (GetCPInfo(CodePage, lpCPInfo));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetCPInfoExW
|
|
Begin=
|
|
CONST WCHAR szUTF7[] = L"UTF-7";
|
|
CONST WCHAR szUTF8[] = L"UTF-8";
|
|
CONST WCHAR szGB18030[] = L"GB 18030";
|
|
|
|
// GetCPInfoExW is wrapped for UTF-7/UTF-8 support, because its on not on Win95,
|
|
// AND for the string containing the code page names, as well. Note that we
|
|
// hardcode the UTF strings rather than make them resources since they are not
|
|
// localized
|
|
BOOL __stdcall
|
|
GodotGetCPInfoExW(UINT CodePage, DWORD dwFlags, LPCPINFOEXW lpCPInfoEx)
|
|
{
|
|
// Begin locals
|
|
BOOL RetVal = FALSE;
|
|
CPINFOEXA CPInfoExAnsi;
|
|
|
|
if (s_pfnGetCPInfoExA == NULL)
|
|
{
|
|
// Must allocate stuff for this API call
|
|
s_pfnGetCPInfoExA = (PFNgciea)GetKernelProc("GetCPInfoExA");
|
|
}
|
|
|
|
if (s_pfnGetCPInfoExA)
|
|
{
|
|
//
|
|
// See if it's a special code page value for UTF translations.
|
|
//
|
|
if (CodePage >= NLS_CP_ALGORITHM_RANGE)
|
|
{
|
|
if (UTFCPInfo(CodePage, (LPCPINFO)lpCPInfoEx, TRUE))
|
|
{
|
|
if (CodePage == CP_UTF8)
|
|
memcpy(lpCPInfoEx->CodePageName, szUTF8, gwcslen(szUTF8));
|
|
else // (CodePage == CP_UTF7)
|
|
memcpy(lpCPInfoEx->CodePageName, szUTF7, gwcslen(szUTF7));
|
|
|
|
return (TRUE);
|
|
}
|
|
return (FALSE);
|
|
}
|
|
|
|
if (CodePage == CP_GB18030)
|
|
{
|
|
if (GB18030Helper(CodePage, NLS_CP_CPINFO, NULL, 0, NULL, 0, (LPCPINFO)lpCPInfoEx))
|
|
{
|
|
|
|
memcpy(lpCPInfoEx->CodePageName, szGB18030, gwcslen(szGB18030));
|
|
return(TRUE);
|
|
}
|
|
return(FALSE);
|
|
}
|
|
|
|
ZeroMemory(&CPInfoExAnsi, sizeof(CPINFOEXA));
|
|
RetVal = (s_pfnGetCPInfoExA(CodePage, dwFlags, &CPInfoExAnsi));
|
|
|
|
// Begin postcall
|
|
if(RetVal != FALSE)
|
|
{
|
|
lpCPInfoEx->MaxCharSize = CPInfoExAnsi.MaxCharSize;
|
|
lpCPInfoEx->DefaultChar[0] = CPInfoExAnsi.DefaultChar[0];
|
|
lpCPInfoEx->DefaultChar[1] = CPInfoExAnsi.DefaultChar[1];
|
|
lpCPInfoEx->LeadByte[0] = CPInfoExAnsi.LeadByte[0];
|
|
lpCPInfoEx->LeadByte[1] = CPInfoExAnsi.LeadByte[1];
|
|
lpCPInfoEx->UnicodeDefaultChar = CPInfoExAnsi.UnicodeDefaultChar;
|
|
lpCPInfoEx->CodePage = CPInfoExAnsi.CodePage;
|
|
MultiByteToWideChar(g_acp, 0, CPInfoExAnsi.CodePageName, -1, lpCPInfoEx->CodePageName, MAX_PATH);
|
|
}
|
|
}
|
|
else
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetCurrentDirectoryW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotGetCurrentDirectoryW(DWORD nBufferLength, LPWSTR lpBuffer)
|
|
{
|
|
// Begin locals
|
|
DWORD RetVal;
|
|
LPSTR lpBufferAnsi;
|
|
|
|
_STACKALLOC((nBufferLength*g_mcs)+1, lpBufferAnsi);
|
|
if(lpBufferAnsi==NULL)
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
// Call the 'A' version of the API
|
|
RetVal=GetCurrentDirectoryA(nBufferLength, lpBufferAnsi);
|
|
|
|
// Begin postcall
|
|
if(RetVal)
|
|
MultiByteToWideChar(g_acp, 0, lpBufferAnsi, -1, lpBuffer, nBufferLength);
|
|
else if (lpBuffer && 0 < nBufferLength)
|
|
*lpBuffer = L'\0';
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetCurrencyFormatW
|
|
Begin=
|
|
int __stdcall
|
|
GodotGetCurrencyFormatW( LCID Locale,
|
|
DWORD dwFlags,
|
|
LPCWSTR lpValue,
|
|
CURRENCYFMTW * lpFormat,
|
|
LPWSTR lpCurrencyStr,
|
|
int cchCurrency
|
|
)
|
|
{
|
|
// Begin locals
|
|
int RetVal;
|
|
LPSTR lpValueAnsi;
|
|
CURRENCYFMTA * lpFormatAnsi;
|
|
LPSTR lpCurrencyStrAnsi;
|
|
UINT cpg = CpgFromLocale(Locale);
|
|
UINT mcs = CbPerChOfCpg(cpg);
|
|
int cchBuff;
|
|
|
|
// Begin precall
|
|
|
|
GODOT_TO_CPG_STACKALLOC(lpValue, lpValueAnsi, cpg, mcs);
|
|
|
|
if (lpFormat == NULL)
|
|
{
|
|
lpFormatAnsi = NULL;
|
|
}
|
|
else
|
|
{
|
|
_STACKALLOC(sizeof(CURRENCYFMTA), lpFormatAnsi);
|
|
ZeroMemory(lpFormatAnsi, sizeof(CURRENCYFMTA));
|
|
lpFormatAnsi->NumDigits = lpFormat->NumDigits;
|
|
lpFormatAnsi->LeadingZero = lpFormat->LeadingZero;
|
|
lpFormatAnsi->Grouping = lpFormat->Grouping;
|
|
GODOT_TO_CPG_STACKALLOC(lpFormat->lpDecimalSep, lpFormatAnsi->lpDecimalSep, cpg, mcs);
|
|
GODOT_TO_CPG_STACKALLOC(lpFormat->lpThousandSep, lpFormatAnsi->lpThousandSep, cpg, mcs);
|
|
lpFormatAnsi->NegativeOrder = lpFormat->NegativeOrder;
|
|
lpFormatAnsi->PositiveOrder = lpFormat->PositiveOrder;
|
|
GODOT_TO_CPG_STACKALLOC(lpFormat->lpCurrencySymbol, lpFormatAnsi->lpCurrencySymbol, cpg, mcs);
|
|
}
|
|
|
|
// Call the 'A' version of the API
|
|
if ((cchCurrency > 0) && FSTRING_VALID(lpCurrencyStr == NULL))
|
|
{
|
|
cchBuff = (cchCurrency*mcs)+1;
|
|
_STACKALLOC(cchBuff, lpCurrencyStrAnsi);
|
|
if(lpCurrencyStrAnsi==NULL)
|
|
{
|
|
return(0);
|
|
}
|
|
ZeroMemory(lpCurrencyStrAnsi, cchBuff);
|
|
RetVal=GetCurrencyFormatA(Locale, dwFlags, lpValueAnsi, lpFormatAnsi, lpCurrencyStrAnsi, cchBuff);
|
|
|
|
if (RetVal > 0)
|
|
MultiByteToWideChar(cpg, 0, lpCurrencyStrAnsi, cchCurrency*mcs, lpCurrencyStr, cchCurrency);
|
|
}
|
|
else
|
|
RetVal=GetCurrencyFormatA(Locale, dwFlags, lpValueAnsi, lpFormatAnsi, NULL, 0);
|
|
|
|
if((RetVal==0) && lpCurrencyStr && (0 < cchCurrency))
|
|
{
|
|
*lpCurrencyStr = '0';
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetCurrentHwProfileW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotGetCurrentHwProfileW(LPHW_PROFILE_INFOW lphpi)
|
|
{
|
|
// Begin locals
|
|
BOOL RetVal = FALSE;
|
|
|
|
if (s_pfnGetCurrentHwProfileA == NULL)
|
|
{
|
|
// Must allocate stuff for this API call
|
|
s_pfnGetCurrentHwProfileA = (PFNgchpa)GetAdvapiProc("GetCurrentHwProfileA");
|
|
}
|
|
|
|
if (s_pfnGetCurrentHwProfileA)
|
|
{
|
|
HW_PROFILE_INFOA hpia;
|
|
|
|
RetVal=(s_pfnGetCurrentHwProfileA(&hpia));
|
|
|
|
// Begin postcall
|
|
if(RetVal)
|
|
{
|
|
lphpi->dwDockInfo = hpia.dwDockInfo;
|
|
MultiByteToWideChar(g_acp, 0,
|
|
hpia.szHwProfileGuid, HW_PROFILE_GUIDLEN,
|
|
lphpi->szHwProfileGuid, HW_PROFILE_GUIDLEN);
|
|
MultiByteToWideChar(g_acp, 0,
|
|
hpia.szHwProfileName, MAX_PROFILE_LEN,
|
|
lphpi->szHwProfileName, MAX_PROFILE_LEN);
|
|
}
|
|
}
|
|
else
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetCharacterPlacementW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotGetCharacterPlacementW( HDC hdc,
|
|
LPCWSTR lpString,
|
|
int nCount,
|
|
int nMaxExtent,
|
|
LPGCP_RESULTSW lpResults,
|
|
DWORD dwFlags
|
|
)
|
|
{
|
|
// Since none of the in params in lpResults need conversion and only ONE out param does,
|
|
// we will simply pass their structure on through and convert the one param if we need to
|
|
DWORD RetVal;
|
|
LPSTR lpStringAnsi;
|
|
LPSTR lpOutStringAnsi;
|
|
size_t lpOutStringLength;
|
|
size_t lStructSizeT;
|
|
BOOL fOutString = (FSTRING_VALID(lpResults->lpOutString));
|
|
UINT cpg = CpgFromHdc(hdc);
|
|
UINT mcs = CbPerChOfCpg(cpg);
|
|
|
|
// Begin precall
|
|
if(lpResults->lStructSize < sizeof(LPGCP_RESULTSW))
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return(0);
|
|
}
|
|
|
|
GODOT_TO_CPG_STACKALLOC(lpString, lpStringAnsi, cpg, mcs);
|
|
if(lpStringAnsi==NULL)
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
// Cache the struct size so we can restore it later
|
|
lStructSizeT = lpResults->lStructSize;
|
|
lpResults->lStructSize = sizeof(LPGCP_RESULTSA);
|
|
|
|
RetVal=GetCharacterPlacementA(hdc,
|
|
lpStringAnsi,
|
|
nCount,
|
|
nMaxExtent,
|
|
(LPGCP_RESULTSA)lpResults,
|
|
dwFlags);
|
|
|
|
// restore the struct size
|
|
lpResults->lStructSize = lStructSizeT;
|
|
|
|
// We will be a little paranoid in case the API did something to the OUT string
|
|
if (fOutString && (RetVal !=0))
|
|
{
|
|
// If the OUT param is there, we need to make that
|
|
// be a UNICODE string (it is an ANSI one right now)
|
|
if (FSTRING_VALID(lpResults->lpOutString))
|
|
{
|
|
lpOutStringLength = lstrlenA( (LPSTR)lpResults->lpOutString);
|
|
_STACKALLOC(lpOutStringLength * mcs, lpOutStringAnsi);
|
|
strcpy(lpOutStringAnsi, (LPSTR)(lpResults->lpOutString));
|
|
MultiByteToWideChar(cpg,
|
|
0,
|
|
lpOutStringAnsi,
|
|
-1,
|
|
lpResults->lpOutString,
|
|
nCount);
|
|
}
|
|
}
|
|
else
|
|
lpResults->lpOutString = NULL;
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetDateFormatW
|
|
Begin=
|
|
int __stdcall
|
|
GodotGetDateFormatW( LCID Locale,
|
|
DWORD dwFlags,
|
|
const SYSTEMTIME * lpDate,
|
|
LPCWSTR lpFormat,
|
|
LPWSTR lpDateStr,
|
|
int cchDate
|
|
)
|
|
{
|
|
// Begin locals
|
|
int RetVal;
|
|
LPSTR lpFormatAnsi;
|
|
UINT cpg;
|
|
UINT mcs;
|
|
|
|
// Begin precall
|
|
if(dwFlags & LOCALE_USE_CP_ACP)
|
|
{
|
|
cpg = g_acp;
|
|
mcs = g_mcs;
|
|
}
|
|
else
|
|
{
|
|
cpg = CpgFromLocale(Locale);
|
|
mcs = CbPerChOfCpg(cpg);
|
|
}
|
|
|
|
GODOT_TO_CPG_STACKALLOC(lpFormat, lpFormatAnsi, cpg, mcs);
|
|
|
|
if(FSTRING_VALID(lpDateStr) && (cchDate > 0))
|
|
{
|
|
LPSTR lpDateStrAnsi;
|
|
|
|
_STACKALLOC((cchDate+1)*mcs, lpDateStrAnsi);
|
|
if(lpDateStrAnsi==NULL)
|
|
{
|
|
return(0);
|
|
}
|
|
RetVal=GetDateFormatA(Locale, dwFlags, lpDate, lpFormatAnsi, lpDateStrAnsi, ((cchDate+1)*mcs));
|
|
if(RetVal && lpDateStr)
|
|
MultiByteToWideChar(cpg, 0, lpDateStrAnsi, cchDate*mcs, lpDateStr, cchDate);
|
|
}
|
|
else
|
|
{
|
|
RetVal=GetDateFormatA(Locale, dwFlags, lpDate, lpFormatAnsi, NULL, 0);
|
|
}
|
|
|
|
if(RetVal==0 && lpDateStr && (0 < cchDate))
|
|
{
|
|
*lpDateStr = '0';
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetDiskFreeSpaceExW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotGetDiskFreeSpaceExW( LPCWSTR lpDirectoryName,
|
|
PULARGE_INTEGER lpFreeBytesAvailableToCaller,
|
|
PULARGE_INTEGER lpTotalNumberOfBytes,
|
|
PULARGE_INTEGER lpTotalNumberOfFreeBytes
|
|
)
|
|
{
|
|
if (!lpFreeBytesAvailableToCaller || !lpTotalNumberOfBytes)
|
|
return FALSE;
|
|
|
|
if (s_pfnGetDiskFreeSpaceExA == NULL)
|
|
{
|
|
// Must allocate stuff for this API call
|
|
s_pfnGetDiskFreeSpaceExA = (PFNgdfsea)GetKernelProc("GetDiskFreeSpaceExA");
|
|
}
|
|
|
|
if (s_pfnGetDiskFreeSpaceExA)
|
|
{
|
|
LPSTR lpDirectoryNameAnsi;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lpDirectoryName, lpDirectoryNameAnsi);
|
|
if(!lpDirectoryNameAnsi && lpDirectoryName)
|
|
return(FALSE);
|
|
|
|
return(s_pfnGetDiskFreeSpaceExA(lpDirectoryNameAnsi,
|
|
lpFreeBytesAvailableToCaller,
|
|
lpTotalNumberOfBytes,
|
|
lpTotalNumberOfFreeBytes));
|
|
|
|
}
|
|
else
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
// Finished
|
|
return FALSE;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetDlgItemTextW
|
|
Begin=
|
|
UINT __stdcall
|
|
GodotGetDlgItemTextW(HWND hDlg, int nIDDlgItem, LPWSTR lpString, int nMaxCount)
|
|
{
|
|
// Begin locals
|
|
UINT RetVal;
|
|
LPSTR lpStringAnsi;
|
|
|
|
_STACKALLOC((nMaxCount*g_mcs)+1, lpStringAnsi);
|
|
if(!lpStringAnsi)
|
|
{
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(0);
|
|
}
|
|
ZeroMemory(lpStringAnsi, (nMaxCount*g_mcs)+1);
|
|
|
|
// Call the 'A' version of the API
|
|
RetVal=GetDlgItemTextA(hDlg, nIDDlgItem, lpStringAnsi, nMaxCount);
|
|
|
|
// Begin postcall
|
|
if(RetVal)
|
|
{
|
|
MultiByteToWideChar(g_acp, 0, lpStringAnsi, -1, lpString, nMaxCount);
|
|
}
|
|
else if (lpString && 0 < nMaxCount)
|
|
{
|
|
*lpString = L'\0';
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetEnvironmentStringsW
|
|
Begin=
|
|
LPWSTR __stdcall
|
|
GodotGetEnvironmentStringsW(void)
|
|
{
|
|
// Begin locals
|
|
LPWSTR RetVal = NULL;
|
|
LPSTR RetValAnsi;
|
|
size_t cch;
|
|
|
|
// Call the 'A' version of the API
|
|
RetValAnsi=GetEnvironmentStringsA();
|
|
|
|
// Begin postcall
|
|
if (RetValAnsi != NULL)
|
|
{
|
|
// Get the size then alloc some memory on the
|
|
// heap; caller can only free it later by calling
|
|
// FreeEnvironmentStringsW, like the docs say.
|
|
cch = (lstrlenA( RetValAnsi)+1);
|
|
RetVal = GodotHeapAlloc(cch*sizeof(WCHAR));
|
|
if (RetVal != NULL)
|
|
{
|
|
MultiByteToWideChar(g_acp, 0, RetValAnsi, -1, RetVal, cch);
|
|
|
|
// On DBCS code pages, this allocation might be bigger than
|
|
// it has to be; if it is, then lets shrink it a bit.
|
|
if(FDBCS_CPG(g_acp))
|
|
{
|
|
size_t cchActual = gwcslen(RetVal);
|
|
if((cchActual + 1) < cch)
|
|
RetVal = (LPWSTR)GodotHeapReAlloc(RetVal, cchActual+1);
|
|
|
|
}
|
|
}
|
|
|
|
// free up the string from the OS, we will have
|
|
// the user free our own later
|
|
FreeEnvironmentStringsA(RetValAnsi);
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetEnvironmentVariableW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotGetEnvironmentVariableW(LPCWSTR lpName, LPWSTR lpBuffer, DWORD nSize)
|
|
{
|
|
// Begin locals
|
|
DWORD RetVal;
|
|
LPSTR lpNameAnsi;
|
|
LPSTR lpBufferAnsi;
|
|
|
|
_STACKALLOC((nSize*g_mcs)+1, lpBufferAnsi);
|
|
if(!lpBufferAnsi)
|
|
{
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(0);
|
|
}
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lpName, lpNameAnsi);
|
|
if(!lpNameAnsi && lpName)
|
|
return(0);
|
|
|
|
RetVal=GetEnvironmentVariableA(lpNameAnsi, lpBufferAnsi, nSize);
|
|
|
|
if(RetVal)
|
|
MultiByteToWideChar(g_acp, 0, lpBufferAnsi, -1, lpBuffer, nSize);
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetEnhMetaFileDescriptionW
|
|
Begin=
|
|
UINT __stdcall
|
|
GodotGetEnhMetaFileDescriptionW(HENHMETAFILE hemf, UINT cchBuffer, LPWSTR lpszDescription)
|
|
{
|
|
// Begin locals
|
|
UINT RetVal;
|
|
LPSTR lpszDescriptionAnsi;
|
|
|
|
if (lpszDescription != NULL)
|
|
{
|
|
_STACKALLOC((cchBuffer*g_mcs)+1, lpszDescriptionAnsi);
|
|
if(lpszDescriptionAnsi==NULL)
|
|
{
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(0);
|
|
}
|
|
ZeroMemory(lpszDescriptionAnsi,(cchBuffer*g_mcs)+1);
|
|
}
|
|
else
|
|
lpszDescriptionAnsi = NULL;
|
|
|
|
// Call the 'A' version of the API
|
|
RetVal=GetEnhMetaFileDescriptionA(hemf, cchBuffer, lpszDescriptionAnsi);
|
|
|
|
// Begin postcall: munge the return value to what is copied to
|
|
// the caller's buffer
|
|
if (lpszDescription && lpszDescriptionAnsi)
|
|
MultiByteToWideChar(g_acp, 0, lpszDescriptionAnsi, -1, lpszDescription, cchBuffer);
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetEnhMetaFileW
|
|
Begin=
|
|
HENHMETAFILE __stdcall
|
|
GodotGetEnhMetaFileW(LPCWSTR lpszMetaFile)
|
|
{
|
|
LPSTR lpszMetaFileAnsi;
|
|
|
|
// Begin precall
|
|
GODOT_TO_ACP_STACKALLOC(lpszMetaFile, lpszMetaFileAnsi);
|
|
if(lpszMetaFileAnsi==NULL)
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
return(GetEnhMetaFileA(lpszMetaFileAnsi));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetFileAttributesExW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotGetFileAttributesExW(LPCWSTR lpFileName, GET_FILEEX_INFO_LEVELS fInfoLevelId, LPVOID lpFileInformation)
|
|
{
|
|
if (s_pfnGetFileAttributesExA == NULL)
|
|
{
|
|
// Must allocate stuff for this API call
|
|
s_pfnGetFileAttributesExA = (PFNgfnaea)GetKernelProc("GetDiskFreeSpaceExA");
|
|
}
|
|
|
|
if (s_pfnGetFileAttributesExA)
|
|
{
|
|
LPSTR lpFileNameAnsi;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lpFileName, lpFileNameAnsi);
|
|
if(!lpFileNameAnsi && lpFileName)
|
|
return(FALSE);
|
|
|
|
return(s_pfnGetFileAttributesExA(lpFileNameAnsi, fInfoLevelId, lpFileInformation));
|
|
}
|
|
else
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetFileTitleW
|
|
Begin=
|
|
short __stdcall
|
|
GodotGetFileTitleW(LPCWSTR lpszFile, LPWSTR lpszTitle, WORD cbBuf)
|
|
{
|
|
// Begin locals
|
|
short RetVal;
|
|
LPSTR lpszFileAnsi;
|
|
LPSTR lpszTitleAnsi;
|
|
|
|
_STACKALLOC((cbBuf*g_mcs)+1, lpszTitleAnsi);
|
|
GODOT_TO_ACP_STACKALLOC(lpszFile, lpszFileAnsi);
|
|
if(lpszTitleAnsi==NULL || (lpszFileAnsi == NULL && lpszFile != NULL))
|
|
{
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(FALSE);
|
|
}
|
|
|
|
RetVal=GetFileTitleA(lpszFileAnsi, lpszTitleAnsi, cbBuf);
|
|
|
|
if(RetVal == 0)
|
|
MultiByteToWideChar(g_acp, 0, lpszTitleAnsi, -1, lpszTitle, cbBuf);
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetFileVersionInfoW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotGetFileVersionInfoW(LPWSTR lptstrFilename, DWORD dwHandle, DWORD dwLen, LPVOID lpData)
|
|
{
|
|
LPSTR lptstrFilenameAnsi;
|
|
BYTE* pbyt;
|
|
|
|
// Make sure we are at least big enough for our special buffer
|
|
if(dwLen <= VERINFO_BUFFER)
|
|
return(FALSE);
|
|
|
|
// Begin precall
|
|
GODOT_TO_ACP_STACKALLOC(lptstrFilename, lptstrFilenameAnsi);
|
|
if(lptstrFilenameAnsi==NULL && lptstrFilename != NULL)
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
pbyt = (BYTE*)lpData + VERINFO_BUFFER;
|
|
|
|
return(GetFileVersionInfoA(lptstrFilenameAnsi, dwHandle, dwLen, (void *)pbyt));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetFileVersionInfoSizeW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotGetFileVersionInfoSizeW(LPWSTR lptstrFilename, LPDWORD lpdwHandle)
|
|
{
|
|
LPSTR lptstrFilenameAnsi;
|
|
DWORD RetVal;
|
|
|
|
// Begin precall
|
|
GODOT_TO_ACP_STACKALLOC(lptstrFilename, lptstrFilenameAnsi);
|
|
if(lptstrFilenameAnsi==NULL && lptstrFilename != NULL)
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
RetVal = GetFileVersionInfoSizeA(lptstrFilenameAnsi, lpdwHandle);
|
|
|
|
// If the call succeeds, add our scratchpad buffer for subsequent calls
|
|
if(RetVal)
|
|
RetVal += VERINFO_BUFFER;
|
|
|
|
return(RetVal);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetFullPathNameW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotGetFullPathNameW(LPCWSTR lpFileName, DWORD nBufferLength, LPWSTR lpBuffer, LPWSTR * lpFilePart)
|
|
{
|
|
// Begin locals
|
|
DWORD RetVal;
|
|
LPSTR lpFileNameAnsi;
|
|
LPSTR lpBufferAnsi;
|
|
LPSTR * lpFilePartAnsi = NULL;
|
|
WCHAR drive[_MAX_DRIVE];
|
|
WCHAR dir[_MAX_DIR];
|
|
UINT cpg = FILES_CPG;
|
|
|
|
_STACKALLOC((nBufferLength*g_mcs)+1, lpBufferAnsi);
|
|
GODOT_TO_CPG_STACKALLOC(lpFileName, lpFileNameAnsi, cpg, g_mcs);
|
|
if((!lpBufferAnsi) ||
|
|
(lpFileName && !lpFileNameAnsi))
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
RetVal=GetFullPathNameA(lpFileNameAnsi, nBufferLength, lpBufferAnsi, lpFilePartAnsi);
|
|
|
|
if(RetVal)
|
|
{
|
|
MultiByteToWideChar(cpg, 0, lpBufferAnsi, -1, lpBuffer, nBufferLength);
|
|
|
|
if(lpFilePart)
|
|
{
|
|
// We ignore lpFilePartAnsi and just derive lpFilePart here
|
|
// (even non-technical folks like CWissink can contribute now and then!)
|
|
gwsplitpath(lpBuffer, drive, dir, NULL, NULL);
|
|
*lpFilePart = lpBuffer + gwcslen(drive) + gwcslen(dir);
|
|
}
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetGlyphOutlineW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotGetGlyphOutlineW(HDC hdc, UINT uChar, UINT uFormat, LPGLYPHMETRICS lpgm,
|
|
DWORD cbBuffer, LPVOID lpvBuffer, const MAT2 * lpmat2)
|
|
{
|
|
UINT uCharA = 0;
|
|
UINT cpg;
|
|
UINT mcs;
|
|
|
|
cpg = CpgFromHdc(hdc);
|
|
mcs = CbPerChOfCpg(cpg);
|
|
|
|
WideCharToMultiByte(cpg, 0, (WCHAR *)&uChar, 1, (CHAR *)&uCharA, mcs, NULL, NULL);
|
|
return(GetGlyphOutlineA(hdc, uCharA, uFormat, lpgm, cbBuffer, lpvBuffer, lpmat2));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetICMProfileW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotGetICMProfileW(HDC hDC, LPDWORD lpcbName, LPWSTR lpszFilename)
|
|
{
|
|
// Begin locals
|
|
BOOL RetVal;
|
|
LPSTR lpszFilenameAnsi;
|
|
|
|
_STACKALLOC((*lpcbName*g_mcs)+1, lpszFilenameAnsi);
|
|
RetVal=GetICMProfileA(hDC, lpcbName, lpszFilenameAnsi);
|
|
|
|
// Begin postcall - make sure to set the return buffer
|
|
// to the actual size of the buffer
|
|
if(RetVal && lpszFilenameAnsi && lpszFilename)
|
|
MultiByteToWideChar(g_acp, 0, lpszFilenameAnsi, -1, lpszFilename, *(lpcbName));
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetJobW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotGetJobW(HANDLE _noname0, DWORD _noname1, DWORD _noname2, LPBYTE _noname3,
|
|
DWORD _noname4, LPDWORD _noname5)
|
|
{
|
|
// ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
|
|
return(GetJobW(_noname0, _noname1, _noname2, _noname3, _noname4, _noname5));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetKerningPairsW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotGetKerningPairsW(HDC hdc, DWORD nNumPairs, LPKERNINGPAIR lpkrnpair)
|
|
{
|
|
DWORD RetVal;
|
|
|
|
// we do not want to make them allocate more memory
|
|
// than they need to, so we will do this mostly in place
|
|
RetVal=GetKerningPairsA(hdc, nNumPairs, lpkrnpair);
|
|
|
|
// Begin postcall
|
|
if((nNumPairs > 0) && (RetVal > 0))
|
|
{
|
|
UINT cpg = CpgFromHdc(hdc);
|
|
UINT mcs = CbPerChOfCpg(cpg);
|
|
WORD wTemp;
|
|
DWORD iPair;
|
|
|
|
for (iPair=0 ; iPair < RetVal ; iPair++)
|
|
{
|
|
wTemp = lpkrnpair[iPair].wFirst;
|
|
lpkrnpair[iPair].wFirst = 0;
|
|
MultiByteToWideChar(cpg, 0, &(char)wTemp, mcs, &(WCHAR)lpkrnpair[iPair].wFirst, 1);
|
|
wTemp = lpkrnpair[iPair].wSecond;
|
|
lpkrnpair[iPair].wSecond = 0;
|
|
MultiByteToWideChar(cpg, 0, &(char)wTemp, mcs, &(WCHAR)lpkrnpair[iPair].wSecond, 1);
|
|
}
|
|
}
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetKeyboardLayoutNameW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotGetKeyboardLayoutNameW(LPWSTR pwszKLID)
|
|
{
|
|
// Begin locals
|
|
BOOL RetVal;
|
|
LPSTR pwszKLIDAnsi;
|
|
|
|
_STACKALLOC((KL_NAMELENGTH *g_mcs)+1, pwszKLIDAnsi);
|
|
if(pwszKLIDAnsi==NULL)
|
|
{
|
|
return(FALSE);
|
|
}
|
|
RetVal=GetKeyboardLayoutNameA(pwszKLIDAnsi);
|
|
|
|
// Begin postcall
|
|
if(RetVal)
|
|
MultiByteToWideChar(g_acp, 0, pwszKLIDAnsi, -1, pwszKLID, gwcslen(pwszKLID));
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetKeyNameTextW
|
|
Begin=
|
|
int __stdcall
|
|
GodotGetKeyNameTextW(LONG lParam, LPWSTR lpString, int nSize)
|
|
{
|
|
int RetVal;
|
|
UINT cpg = CpgFromLocale(LOWORD(GetKeyboardLayout(0)));
|
|
UINT mcs = CbPerChOfCpg(cpg);
|
|
LPSTR lpStringAnsi = GodotHeapAlloc((nSize*mcs) + 1);
|
|
|
|
if(lpStringAnsi==NULL)
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(0);
|
|
}
|
|
RetVal=GetKeyNameTextA(lParam, lpStringAnsi, nSize);
|
|
|
|
|
|
if(RetVal)
|
|
MultiByteToWideChar(cpg, 0, lpStringAnsi, nSize*mcs, lpString, nSize);
|
|
|
|
GodotHeapFree(lpStringAnsi);
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetLocaleInfoW
|
|
Begin=
|
|
|
|
#define NLS_GET_LCTYPE_VALUE(x) (x & ~(LOCALE_NOUSEROVERRIDE | \
|
|
LOCALE_USE_CP_ACP | \
|
|
LOCALE_RETURN_NUMBER))
|
|
|
|
int __stdcall
|
|
GodotGetLocaleInfoW(LCID Locale, LCTYPE LCType, LPWSTR lpLCData, int cchData)
|
|
{
|
|
LCTYPE LCTypeT = NLS_GET_LCTYPE_VALUE(LCType);
|
|
|
|
// a little validation LOCALE_RETURN_NUMBER checks
|
|
if ((LCType & LOCALE_RETURN_NUMBER) & (FWIN95()))
|
|
|
|
{
|
|
// NT/Win2000 return this error if you ask for a number on a string LCType,
|
|
// So for Win95 we will do the same if you pass this flag at all.
|
|
SetLastError(ERROR_INVALID_FLAGS);
|
|
return (0);
|
|
}
|
|
|
|
if((LCTypeT == LOCALE_RETURN_NUMBER) && (LCTypeT == LOCALE_FONTSIGNATURE))
|
|
{
|
|
// Pass back the unconverted number if thats what they are asking for.
|
|
// Also, do not convert font signatures since those are not really strings.
|
|
return(GetLocaleInfoA(Locale, LCType, (LPSTR)lpLCData, cchData));
|
|
}
|
|
else
|
|
{
|
|
int RetVal;
|
|
LPSTR lpLCDataAnsi;
|
|
UINT cpg;
|
|
UINT mcs;
|
|
|
|
if (LCType & LOCALE_USE_CP_ACP)
|
|
{
|
|
cpg = g_acp;
|
|
mcs = g_mcs;
|
|
}
|
|
else
|
|
{
|
|
cpg = CpgFromLocale(Locale);
|
|
mcs = CbPerChOfCpg(cpg);
|
|
}
|
|
|
|
_STACKALLOC((cchData+1)*mcs, lpLCDataAnsi);
|
|
if(lpLCDataAnsi==NULL)
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
RetVal=GetLocaleInfoA(Locale, LCType, lpLCDataAnsi, cchData);
|
|
|
|
if (RetVal)
|
|
{
|
|
// Its a string, so lets convert it
|
|
MultiByteToWideChar(cpg, 0, lpLCDataAnsi, cchData*mcs, lpLCData, cchData);
|
|
}
|
|
else if (lpLCData && 0 < cchData)
|
|
{
|
|
*lpLCData = L'\0';
|
|
}
|
|
|
|
|
|
return RetVal;
|
|
}
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetLogColorSpaceW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotGetLogColorSpaceW(HCOLORSPACE hColorSpace, LPLOGCOLORSPACEW lcsw, DWORD nSize)
|
|
{
|
|
// Begin locals
|
|
BOOL RetVal;
|
|
LOGCOLORSPACEA lcsa;
|
|
|
|
ZeroMemory(&lcsa, sizeof(LOGCOLORSPACEA));
|
|
RetVal=GetLogColorSpaceA(hColorSpace, &lcsa, nSize);
|
|
|
|
// Begin postcall
|
|
if(RetVal)
|
|
{
|
|
memcpy(lcsw, &lcsa, 6*sizeof(DWORD)+sizeof(LCSCSTYPE)+sizeof(LCSGAMUTMATCH)+sizeof(CIEXYZTRIPLE));
|
|
|
|
if(FSTRING_VALID(lcsw->lcsFilename))
|
|
MultiByteToWideChar(g_acp, 0, lcsa.lcsFilename, -1, lcsw->lcsFilename, MAX_PATH);
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetLogicalDriveStringsW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotGetLogicalDriveStringsW(DWORD nBufferLength, LPWSTR lpBuffer)
|
|
{
|
|
// Begin locals
|
|
DWORD RetVal;
|
|
LPSTR lpBufferAnsi;
|
|
|
|
_STACKALLOC((nBufferLength*g_mcs)+1, lpBufferAnsi);
|
|
if(lpBufferAnsi==NULL)
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
RetVal=GetLogicalDriveStringsA(nBufferLength, lpBufferAnsi);
|
|
|
|
// Begin postcall
|
|
if(RetVal && (RetVal<=nBufferLength))
|
|
{
|
|
// Do not muck with the return value. We have to hope that the
|
|
// value will accurately tell the caller when their buffer was
|
|
// not big enough.
|
|
MultiByteToWideChar(g_acp, 0, lpBufferAnsi, -1, lpBuffer, nBufferLength);
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetLongPathNameW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotGetLongPathNameW(LPCWSTR lpszShortPath, LPWSTR lpszLongPath, DWORD cchBuffer)
|
|
{
|
|
// Begin locals
|
|
DWORD RetVal = 0;
|
|
|
|
if (s_pfnGetLongPathNameA == NULL)
|
|
{
|
|
// Must allocate stuff for this API call
|
|
s_pfnGetLongPathNameA = (PFNglpna)GetKernelProc("GetLongPathNameA");
|
|
}
|
|
|
|
if (s_pfnGetLongPathNameA)
|
|
{
|
|
LPSTR lpszShortPathAnsi;
|
|
LPSTR lpszLongPathAnsi;
|
|
UINT cpg = FILES_CPG;
|
|
|
|
_STACKALLOC((cchBuffer*g_mcs)+1, lpszLongPathAnsi);
|
|
GODOT_TO_CPG_STACKALLOC(lpszShortPath, lpszShortPathAnsi, cpg, g_mcs);
|
|
if(!lpszShortPathAnsi && lpszShortPath)
|
|
return(0);
|
|
|
|
RetVal = (s_pfnGetLongPathNameA(lpszShortPathAnsi, lpszLongPathAnsi, cchBuffer));
|
|
|
|
if(RetVal && (RetVal<=cchBuffer))
|
|
MultiByteToWideChar(g_acp, 0, lpszLongPathAnsi, -1, lpszLongPath, cchBuffer);
|
|
}
|
|
else
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetMenuItemInfoW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotGetMenuItemInfoW(HMENU hMenu, UINT uItem, BOOL fByPosition, LPMENUITEMINFOW lpmiiw)
|
|
{
|
|
// Begin locals
|
|
BOOL RetVal;
|
|
MENUITEMINFOA miia;
|
|
BOOL fAlloc = MenuItemInfoAfromW(&miia, lpmiiw);
|
|
|
|
RetVal=GetMenuItemInfoA(hMenu, uItem, fByPosition, &miia);
|
|
|
|
// Begin postcall
|
|
if(RetVal)
|
|
{
|
|
memcpy(lpmiiw, &miia, (5*sizeof(UINT)+3*sizeof(HANDLE)+sizeof(ULONG_PTR)));
|
|
if(fAlloc)
|
|
{
|
|
MultiByteToWideChar(g_acp, 0, miia.dwTypeData, miia.cch, lpmiiw->dwTypeData, lpmiiw->cch);
|
|
lpmiiw->cch = gwcslen(lpmiiw->dwTypeData);
|
|
}
|
|
else
|
|
{
|
|
lpmiiw->dwTypeData = (LPWSTR)miia.dwTypeData;
|
|
lpmiiw->cch = sizeof(lpmiiw->dwTypeData);
|
|
}
|
|
}
|
|
|
|
if(fAlloc)
|
|
GodotHeapFree(miia.dwTypeData);
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetMenuStringW
|
|
Begin=
|
|
int __stdcall
|
|
GodotGetMenuStringW(HMENU hMenu, UINT uIDItem, LPWSTR lpString, int nMaxCount, UINT uFlag)
|
|
{
|
|
// Begin locals
|
|
int RetVal;
|
|
LPSTR lpStringAnsi = NULL;
|
|
|
|
_STACKALLOC((nMaxCount * g_mcs) + 1, lpStringAnsi);
|
|
if(lpStringAnsi==NULL)
|
|
{
|
|
return(0);
|
|
}
|
|
ZeroMemory(lpStringAnsi, (nMaxCount * g_mcs) + 1);
|
|
|
|
// Call the 'A' version of the API
|
|
RetVal=GetMenuStringA(hMenu, uIDItem, lpStringAnsi, nMaxCount, uFlag);
|
|
|
|
// Begin postcall
|
|
if(RetVal && lpStringAnsi && lpString)
|
|
MultiByteToWideChar(g_acp, 0, lpStringAnsi, -1, lpString, (RetVal + 1));
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetMessageW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotGetMessageW(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax)
|
|
{
|
|
return(GodotReceiveMessage(mtGetMessage, lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, 0));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetModuleFileNameW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotGetModuleFileNameW(HMODULE hModule, LPWSTR lpFilename, DWORD nSize)
|
|
{
|
|
// Begin locals
|
|
DWORD RetVal;
|
|
LPSTR lpFilenameAnsi;
|
|
|
|
_STACKALLOC((nSize*g_mcs)+1, lpFilenameAnsi);
|
|
if(!lpFilenameAnsi)
|
|
{
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(FALSE);
|
|
}
|
|
|
|
// Call the 'A' version of the API
|
|
RetVal=GetModuleFileNameA(hModule, lpFilenameAnsi, nSize);
|
|
|
|
// Begin postcall. Per the PSDK: For the ANSI version of the function, the number
|
|
// of TCHARs is the number of bytes; for the Unicode version, it is the number of
|
|
// characters.
|
|
// CONSIDER: Optimize the return value for the case where the buffer was not big
|
|
// enough?
|
|
if(RetVal)
|
|
{
|
|
MultiByteToWideChar(g_acp, 0, lpFilenameAnsi, -1, lpFilename, nSize);
|
|
RetVal = gwcslen(lpFilename);
|
|
}
|
|
else if (lpFilename && 0 < nSize)
|
|
*lpFilename = L'\0';
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetMonitorInfoW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotGetMonitorInfoW(HMONITOR hMonitor, LPMONITORINFO lpmi)
|
|
{
|
|
// Begin locals
|
|
BOOL RetVal = FALSE;
|
|
|
|
if (s_pfnGetMonitorInfoA == NULL)
|
|
{
|
|
// Must allocate stuff for this API call
|
|
s_pfnGetMonitorInfoA = (PFNgmia)GetUserProc("GetMonitorInfoA");
|
|
}
|
|
|
|
if (s_pfnGetMonitorInfoA)
|
|
{
|
|
// Only need to convert anything if caller gave us an EX structure
|
|
if(lpmi->cbSize == sizeof(MONITORINFOEXW))
|
|
{
|
|
MONITORINFOEXA mia;
|
|
|
|
ZeroMemory(&mia, sizeof(MONITORINFOEXA));
|
|
memcpy(&mia, lpmi, (2 * sizeof(DWORD)) + (2 * (sizeof(RECT))));
|
|
mia.cbSize = sizeof(MONITORINFOEXA);
|
|
WideCharToMultiByte(g_acp, 0,
|
|
((LPMONITORINFOEXW)lpmi)->szDevice, CCHDEVICENAME,
|
|
mia.szDevice, CCHDEVICENAME,
|
|
NULL, NULL);
|
|
RetVal = (s_pfnGetMonitorInfoA (hMonitor, (LPMONITORINFO)&mia));
|
|
if(RetVal)
|
|
{
|
|
memcpy(lpmi, &mia, (2 * sizeof(DWORD)) + (2 * (sizeof(RECT))));
|
|
MultiByteToWideChar(g_acp, 0,
|
|
mia.szDevice, -1,
|
|
((LPMONITORINFOEXW)lpmi)->szDevice, CCHDEVICENAME);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
RetVal = (s_pfnGetMonitorInfoA (hMonitor, lpmi));
|
|
}
|
|
}
|
|
else
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetObjectW
|
|
Begin=
|
|
int __stdcall
|
|
GodotGetObjectW(HGDIOBJ hgdiobj, int cbBuffer, LPVOID lpvObject)
|
|
{
|
|
// Begin locals
|
|
int RetVal;
|
|
|
|
if(GetObjectType(hgdiobj) == OBJ_FONT)
|
|
{
|
|
LOGFONTA lfa;
|
|
|
|
RetVal=GetObjectA(hgdiobj, cbBuffer, &lfa);
|
|
|
|
if(RetVal==sizeof(LOGFONTA))
|
|
{
|
|
// Make sure they gave us an object and did not lie about the
|
|
// size. Found this bug with the Visio Editor test integration.
|
|
if(lpvObject)
|
|
LogFontWfromA((LPLOGFONTW)lpvObject, &lfa);
|
|
RetVal = sizeof(LOGFONTW);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
RetVal=GetObjectA(hgdiobj, cbBuffer, lpvObject);
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetOpenFileNameW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotGetOpenFileNameW(LPOPENFILENAMEW lpofn)
|
|
{
|
|
return(GetOpenSaveFileHelper(lpofn, TRUE));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetOpenFileNamePreviewW
|
|
Begin=
|
|
BOOL __stdcall GodotGetOpenFileNamePreviewW(LPOPENFILENAMEW lpofn)
|
|
{
|
|
// ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
|
|
return(FALSE);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetNamedPipeHandleStateW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotGetNamedPipeHandleStateW( HANDLE hNamedPipe,
|
|
LPDWORD lpState,
|
|
LPDWORD lpCurInstances,
|
|
LPDWORD lpMaxCollectionCount,
|
|
LPDWORD lpCollectDataTimeout,
|
|
LPWSTR lpUserName,
|
|
DWORD nMaxUserNameSize
|
|
)
|
|
{
|
|
// Begin locals
|
|
BOOL RetVal;
|
|
LPSTR lpUserNameAnsi;
|
|
|
|
if(lpUserName)
|
|
{
|
|
_STACKALLOC((nMaxUserNameSize*g_mcs)+1, lpUserNameAnsi);
|
|
if(!lpUserNameAnsi)
|
|
{
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(FALSE);
|
|
}
|
|
}
|
|
else
|
|
lpUserNameAnsi = NULL;
|
|
|
|
RetVal=GetNamedPipeHandleStateA(hNamedPipe,
|
|
lpState,
|
|
lpCurInstances,
|
|
lpMaxCollectionCount,
|
|
lpCollectDataTimeout,
|
|
lpUserNameAnsi,
|
|
nMaxUserNameSize
|
|
);
|
|
|
|
// Begin postcall
|
|
if (RetVal && FSTRING_VALID(lpUserName) && FSTRING_VALID(lpUserNameAnsi))
|
|
MultiByteToWideChar(g_acp, 0, lpUserNameAnsi, -1, lpUserName, nMaxUserNameSize);
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetNumberFormatW
|
|
Begin=
|
|
int __stdcall
|
|
GodotGetNumberFormatW( LCID Locale,
|
|
DWORD dwFlags,
|
|
LPCWSTR lpValue,
|
|
const NUMBERFMTW * lpFormat,
|
|
LPWSTR lpNumberStr,
|
|
int cchNumber
|
|
)
|
|
{
|
|
// Begin locals
|
|
int RetVal;
|
|
LPSTR lpValueAnsi;
|
|
UINT cpg = CpgFromLocale(Locale);
|
|
UINT mcs = CbPerChOfCpg(cpg);
|
|
NUMBERFMTA * lpFormatAnsi;
|
|
NUMBERFMTA FormatAnsi;
|
|
|
|
// Begin precall
|
|
GODOT_TO_CPG_STACKALLOC(lpValue, lpValueAnsi, cpg, mcs);
|
|
|
|
if (lpFormat == NULL)
|
|
lpFormatAnsi = NULL;
|
|
else
|
|
{
|
|
ZeroMemory(&FormatAnsi, sizeof(NUMBERFMTA));
|
|
memcpy(&FormatAnsi, lpFormat, (3*sizeof(UINT)));
|
|
GODOT_TO_CPG_STACKALLOC(lpFormat->lpDecimalSep, FormatAnsi.lpDecimalSep, cpg, mcs);
|
|
GODOT_TO_CPG_STACKALLOC(lpFormat->lpThousandSep, FormatAnsi.lpThousandSep, cpg, mcs);
|
|
FormatAnsi.NegativeOrder = lpFormat->NegativeOrder;
|
|
lpFormatAnsi = &FormatAnsi;
|
|
}
|
|
|
|
if ((cchNumber > 0) && FSTRING_VALID(lpNumberStr))
|
|
{
|
|
size_t cchBuff = (cchNumber+1)*mcs;
|
|
LPSTR lpNumberStrAnsi;
|
|
|
|
_STACKALLOC(cchBuff, lpNumberStrAnsi);
|
|
if(!lpNumberStrAnsi)
|
|
{
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(0);
|
|
}
|
|
RetVal=GetNumberFormatA(Locale, dwFlags, lpValueAnsi, lpFormatAnsi, lpNumberStrAnsi, cchBuff);
|
|
|
|
if(RetVal > 0)
|
|
MultiByteToWideChar(cpg, 0, lpNumberStrAnsi, RetVal, lpNumberStr, cchNumber);
|
|
}
|
|
else
|
|
RetVal=GetNumberFormatA(Locale, dwFlags, lpValueAnsi, lpFormatAnsi, NULL, 0);
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetOutlineTextMetricsW
|
|
Begin=
|
|
UINT __stdcall
|
|
GodotGetOutlineTextMetricsW(HDC hdc, UINT cbData, LPOUTLINETEXTMETRICW lpOTM)
|
|
{
|
|
// Begin locals
|
|
UINT RetVal;
|
|
int cOTM;
|
|
LPOUTLINETEXTMETRICA lpOTMAnsi = NULL;
|
|
OUTLINETEXTMETRICW otm;
|
|
int i;
|
|
|
|
// Begin precall
|
|
if((lpOTM != NULL) && (cbData > 0))
|
|
{
|
|
cOTM = (sizeof(OUTLINETEXTMETRICW)/cbData);
|
|
_STACKALLOC(sizeof(OUTLINETEXTMETRICA)*cOTM, lpOTMAnsi);
|
|
ZeroMemory(lpOTMAnsi, (sizeof(OUTLINETEXTMETRICA)*cOTM));
|
|
}
|
|
else
|
|
{
|
|
lpOTMAnsi = NULL;
|
|
cOTM = 0;
|
|
}
|
|
|
|
// Call the 'A' version of the API
|
|
RetVal=GetOutlineTextMetricsA(hdc, cbData, lpOTMAnsi);
|
|
|
|
// Begin postcall
|
|
if (lpOTM == NULL)
|
|
{
|
|
if(RetVal > 0)
|
|
// We need to return something sensible here: the size of
|
|
// OUTLINETEXTMETRICW structures.
|
|
RetVal = (sizeof(OUTLINETEXTMETRICW) * (RetVal / sizeof(OUTLINETEXTMETRICA)));
|
|
}
|
|
else
|
|
{
|
|
if(RetVal > 0 && lpOTMAnsi)
|
|
{
|
|
cOTM = (RetVal / sizeof(OUTLINETEXTMETRICA));
|
|
otm = *lpOTM;
|
|
for (i=0; i < cOTM; i++)
|
|
{
|
|
lpOTM->otmSize = sizeof(OUTLINETEXTMETRICW);
|
|
memcpy(lpOTM, lpOTMAnsi, sizeof(OUTLINETEXTMETRICW));
|
|
TextMetricWfromA(&lpOTM->otmTextMetrics, &lpOTMAnsi->otmTextMetrics);
|
|
|
|
lpOTM++;
|
|
lpOTMAnsi++;
|
|
}
|
|
lpOTM = &otm;
|
|
}
|
|
}
|
|
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetPrinterW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotGetPrinterW(HANDLE _noname0, DWORD _noname1, LPBYTE _noname2, DWORD _noname3, LPDWORD _noname4)
|
|
{
|
|
// ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
|
|
return(GetPrinterW(_noname0, _noname1, _noname2, _noname3, _noname4));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetPrinterDataW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotGetPrinterDataW(HANDLE _noname0, LPWSTR _noname1, LPDWORD _noname2, LPBYTE _noname3,
|
|
DWORD _noname4, LPDWORD _noname5)
|
|
{
|
|
// ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
|
|
return(GetPrinterDataW(_noname0, _noname1, _noname2, _noname3, _noname4, _noname5));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetPrinterDriverW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotGetPrinterDriverW(HANDLE _noname0, LPWSTR _noname1, DWORD _noname2, LPBYTE _noname3,
|
|
DWORD _noname4, LPDWORD _noname5)
|
|
{
|
|
// ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
|
|
return(GetPrinterDriverW(_noname0, _noname1, _noname2, _noname3, _noname4, _noname5));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetPrinterDriverDirectoryW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotGetPrinterDriverDirectoryW( LPWSTR pName,
|
|
LPWSTR pEnvironment,
|
|
DWORD Level,
|
|
LPBYTE pDriverDirectory,
|
|
DWORD cbBuf,
|
|
LPDWORD pcbNeeded
|
|
)
|
|
{
|
|
BOOL RetVal = FALSE;
|
|
LPSTR pNameAnsi = NULL;
|
|
LPSTR pEnvironmentAnsi = NULL;
|
|
LPBYTE pDriverDirectoryA;
|
|
ALLOCRETURN arName;
|
|
ALLOCRETURN arEnvironmentName;
|
|
|
|
// cbBuf is number of bytes, which is at a minimum
|
|
// big enough to hold the ANSI string
|
|
_STACKALLOC(cbBuf + 1, pDriverDirectoryA);
|
|
if(pDriverDirectoryA == NULL)
|
|
{
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(FALSE);
|
|
}
|
|
|
|
arName = GodotToAcpOnHeap(pName, &pNameAnsi);
|
|
arEnvironmentName = GodotToAcpOnHeap(pEnvironment, &pEnvironmentAnsi);
|
|
RetVal=GetPrinterDriverDirectoryA(pNameAnsi,
|
|
pEnvironmentAnsi,
|
|
Level,
|
|
pDriverDirectoryA,
|
|
cbBuf,
|
|
pcbNeeded);
|
|
|
|
if(RetVal)
|
|
{
|
|
MultiByteToWideChar(g_acp, 0,
|
|
(LPSTR)pDriverDirectoryA, -1,
|
|
(LPWSTR)pDriverDirectory, cbBuf / sizeof(WCHAR));
|
|
if(pcbNeeded)
|
|
*pcbNeeded = gwcslen((LPWSTR)pDriverDirectory);
|
|
}
|
|
else
|
|
{
|
|
if(pcbNeeded)
|
|
*pcbNeeded *= 2;
|
|
}
|
|
|
|
if(arName==arAlloc)
|
|
GodotHeapFree(pNameAnsi);
|
|
if(arEnvironmentName==arAlloc)
|
|
GodotHeapFree(pEnvironmentAnsi);
|
|
|
|
if(arName == arFailed || arEnvironmentName == arFailed)
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return RetVal;
|
|
}
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetPrintProcessorDirectoryW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotGetPrintProcessorDirectoryW( LPWSTR pName,
|
|
LPWSTR pEnvironment,
|
|
DWORD Level,
|
|
LPBYTE pPrintProcessorInfo,
|
|
DWORD cbBuf,
|
|
LPDWORD pcbNeeded
|
|
)
|
|
{
|
|
BOOL RetVal = FALSE;
|
|
LPSTR pNameAnsi = NULL;
|
|
LPSTR pEnvironmentAnsi = NULL;
|
|
LPBYTE pPrintProcessorInfoA;
|
|
ALLOCRETURN arName;
|
|
ALLOCRETURN arEnvironmentName;
|
|
|
|
// cbBuf is number of bytes, which is at a minimum
|
|
// big enough to hold the ANSI string
|
|
_STACKALLOC(cbBuf + 1, pPrintProcessorInfoA);
|
|
if(pPrintProcessorInfoA == NULL)
|
|
{
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(FALSE);
|
|
}
|
|
|
|
arName = GodotToAcpOnHeap(pName, &pNameAnsi);
|
|
arEnvironmentName = GodotToAcpOnHeap(pEnvironment, &pEnvironmentAnsi);
|
|
RetVal=GetPrintProcessorDirectoryA(pNameAnsi,
|
|
pEnvironmentAnsi,
|
|
Level,
|
|
pPrintProcessorInfoA,
|
|
cbBuf,
|
|
pcbNeeded);
|
|
|
|
if(RetVal)
|
|
{
|
|
MultiByteToWideChar(g_acp, 0,
|
|
(LPSTR)pPrintProcessorInfoA, -1,
|
|
(LPWSTR)pPrintProcessorInfo, cbBuf / sizeof(WCHAR));
|
|
if(pcbNeeded)
|
|
*pcbNeeded = gwcslen((LPWSTR)pPrintProcessorInfo);
|
|
}
|
|
else
|
|
{
|
|
if(pcbNeeded)
|
|
*pcbNeeded *= sizeof(WCHAR);
|
|
}
|
|
|
|
if(arName==arAlloc)
|
|
GodotHeapFree(pNameAnsi);
|
|
if(arEnvironmentName==arAlloc)
|
|
GodotHeapFree(pEnvironmentAnsi);
|
|
|
|
if(arName == arFailed || arEnvironmentName == arFailed)
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetPrivateProfileSectionW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotGetPrivateProfileSectionW(LPCWSTR lpAppName, LPWSTR lpReturnedString, DWORD nSize, LPCWSTR lpFileName)
|
|
{
|
|
// Begin locals
|
|
DWORD RetVal;
|
|
LPSTR lpAppNameAnsi;
|
|
char lpFileNameAnsi[MAX_PATH + 1];
|
|
LPSTR lpReturnedStringAnsi;
|
|
|
|
_STACKALLOC((nSize*g_mcs)+1, lpReturnedStringAnsi);
|
|
if(!lpReturnedStringAnsi)
|
|
return(0);
|
|
GODOT_TO_ACP_STACKALLOC(lpAppName, lpAppNameAnsi);
|
|
if(!lpAppNameAnsi && lpAppName)
|
|
{
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(0);
|
|
}
|
|
WideCharToMultiByte(g_acp, 0, lpFileName, -1, lpFileNameAnsi, MAX_PATH, NULL, NULL);
|
|
|
|
RetVal=GetPrivateProfileSectionA(lpAppNameAnsi, lpReturnedStringAnsi, nSize, lpFileNameAnsi);
|
|
|
|
if(RetVal)
|
|
RetVal = GrszToGrwz(lpReturnedStringAnsi, lpReturnedString, nSize);
|
|
else if(lpReturnedString)
|
|
{
|
|
*lpReturnedString = '\0';
|
|
}
|
|
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetPrivateProfileSectionNamesW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotGetPrivateProfileSectionNamesW(LPWSTR lpszReturnBuffer, DWORD nSize, LPCWSTR lpFileName)
|
|
{
|
|
// Begin locals
|
|
DWORD RetVal;
|
|
char lpFileNameAnsi[MAX_PATH + 1];
|
|
LPSTR lpszReturnBufferAnsi;
|
|
|
|
_STACKALLOC((nSize*g_mcs)+1, lpszReturnBufferAnsi);
|
|
if(!lpszReturnBufferAnsi)
|
|
{
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(0);
|
|
}
|
|
ZeroMemory(lpszReturnBufferAnsi, (nSize*g_mcs)+1);
|
|
WideCharToMultiByte(g_acp, 0, lpFileName, -1, lpFileNameAnsi, MAX_PATH, NULL, NULL);
|
|
|
|
RetVal=GetPrivateProfileSectionNamesA(lpszReturnBufferAnsi, nSize, lpFileNameAnsi);
|
|
|
|
if(RetVal)
|
|
RetVal = GrszToGrwz(lpszReturnBufferAnsi, lpszReturnBuffer, nSize);
|
|
else if(lpszReturnBuffer)
|
|
{
|
|
*lpszReturnBuffer = '\0';
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetPrivateProfileStringW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotGetPrivateProfileStringW( LPCWSTR lpAppName,
|
|
LPCWSTR lpKeyName,
|
|
LPCWSTR lpDefault,
|
|
LPWSTR lpReturnedString,
|
|
DWORD nSize,
|
|
LPCWSTR lpFileName
|
|
)
|
|
{
|
|
// Begin locals
|
|
DWORD RetVal;
|
|
LPSTR lpAppNameAnsi, lpKeyNameAnsi, lpDefaultAnsi;
|
|
LPSTR lpszRet;
|
|
char lpFileNameAnsi[MAX_PATH + 1];
|
|
|
|
_STACKALLOC((nSize*g_mcs)+1, lpszRet);
|
|
if(lpszRet==NULL)
|
|
{
|
|
return(0);
|
|
}
|
|
WideCharToMultiByte(g_acp, 0, lpFileName, -1, lpFileNameAnsi, MAX_PATH, NULL, NULL);
|
|
GODOT_TO_ACP_STACKALLOC(lpAppName, lpAppNameAnsi);
|
|
GODOT_TO_ACP_STACKALLOC(lpKeyName, lpKeyNameAnsi);
|
|
GODOT_TO_ACP_STACKALLOC(lpDefault, lpDefaultAnsi);
|
|
if((!lpAppNameAnsi && lpAppName) ||
|
|
(!lpKeyNameAnsi && lpKeyName) ||
|
|
(!lpDefaultAnsi && lpDefault))
|
|
return(0);
|
|
|
|
RetVal=GetPrivateProfileStringA(lpAppNameAnsi,
|
|
lpKeyNameAnsi,
|
|
lpDefaultAnsi,
|
|
lpszRet,
|
|
nSize,
|
|
lpFileNameAnsi);
|
|
|
|
if(RetVal)
|
|
MultiByteToWideChar(g_acp, 0, lpszRet, -1, lpReturnedString, nSize);
|
|
else if(lpReturnedString)
|
|
{
|
|
*lpReturnedString = '\0';
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetProcAddress
|
|
Begin=
|
|
FARPROC __stdcall
|
|
GodotGetProcAddress(HMODULE hModule, LPCSTR lpProcName)
|
|
{
|
|
// We do not wrap this function to convert strings; we wrap it because
|
|
// we need to work around the InitMultipleMonitorStubs code in multimon.h
|
|
// which has its own little delayload implementation built in.
|
|
if((GetUserHandle() == hModule) &&
|
|
(strcmp(lpProcName, "GetMonitorInfoW") == 0))
|
|
{
|
|
return((FARPROC)&GodotGetMonitorInfoW);
|
|
}
|
|
|
|
return(GetProcAddress(hModule, lpProcName));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetProfileSectionW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotGetProfileSectionW(LPCWSTR lpAppName, LPWSTR lpReturnedString, DWORD nSize)
|
|
{
|
|
// Begin locals
|
|
DWORD RetVal;
|
|
LPSTR lpAppNameAnsi;
|
|
LPSTR lpReturnedStringAnsi;
|
|
|
|
_STACKALLOC((nSize*g_mcs)+1, lpReturnedStringAnsi);
|
|
GODOT_TO_ACP_STACKALLOC(lpAppName, lpAppNameAnsi);
|
|
if((!lpReturnedStringAnsi) ||
|
|
(lpAppName && !lpAppNameAnsi))
|
|
{
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(FALSE);
|
|
}
|
|
|
|
RetVal=GetProfileSectionA(lpAppNameAnsi, lpReturnedStringAnsi, nSize);
|
|
|
|
if(RetVal)
|
|
GrszToGrwz(lpReturnedStringAnsi, lpReturnedString, nSize);
|
|
else if(lpReturnedString)
|
|
{
|
|
*lpReturnedString = '\0';
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetProfileStringW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotGetProfileStringW( LPCWSTR lpAppName,
|
|
LPCWSTR lpKeyName,
|
|
LPCWSTR lpDefault,
|
|
LPWSTR lpReturnedString,
|
|
DWORD nSize
|
|
)
|
|
{
|
|
// Begin locals
|
|
DWORD RetVal;
|
|
LPSTR lpAppNameAnsi, lpKeyNameAnsi, lpDefaultAnsi;
|
|
LPSTR lpReturnedStringAnsi;
|
|
|
|
_STACKALLOC((nSize*g_mcs)+1, lpReturnedStringAnsi);
|
|
if(!lpReturnedStringAnsi)
|
|
{
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(0);
|
|
}
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lpAppName, lpAppNameAnsi);
|
|
GODOT_TO_ACP_STACKALLOC(lpKeyName, lpKeyNameAnsi);
|
|
GODOT_TO_ACP_STACKALLOC(lpDefault, lpDefaultAnsi);
|
|
if((!lpAppNameAnsi && lpAppName) ||
|
|
(!lpKeyNameAnsi && lpKeyName) ||
|
|
(!lpDefaultAnsi && lpDefault))
|
|
return(0);
|
|
ZeroMemory(lpReturnedStringAnsi, (nSize*g_mcs)+1);
|
|
|
|
RetVal=GetProfileStringA(lpAppNameAnsi, lpKeyNameAnsi, lpDefaultAnsi, lpReturnedStringAnsi, nSize);
|
|
|
|
if(RetVal)
|
|
MultiByteToWideChar(g_acp, 0, lpReturnedStringAnsi, -1, lpReturnedString, nSize);
|
|
else if(lpReturnedString)
|
|
{
|
|
*lpReturnedString = '\0';
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetPropA
|
|
Begin=
|
|
HANDLE __stdcall
|
|
GodotGetPropA(HWND hWnd, LPCSTR lpString)
|
|
{
|
|
if(IsInternalWindowProperty((LPWSTR)lpString, FALSE))
|
|
return(FALSE);
|
|
|
|
return(GetPropA(hWnd, lpString));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetPropW
|
|
Begin=
|
|
HANDLE __stdcall
|
|
GodotGetPropW( HWND hWnd, LPCWSTR lpString)
|
|
{
|
|
LPSTR lpStringAnsi;
|
|
|
|
if(IsInternalWindowProperty(lpString, TRUE))
|
|
return(FALSE);
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lpString, lpStringAnsi);
|
|
if(!lpStringAnsi && lpString)
|
|
return(0);
|
|
|
|
return(GetPropA(hWnd, lpStringAnsi));
|
|
}
|
|
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetRoleTextW
|
|
Begin=
|
|
UINT __stdcall GodotGetRoleTextW(DWORD lRole, LPWSTR lpszRole, UINT cchRoleMax)
|
|
{
|
|
UINT RetVal = 0;
|
|
|
|
if (s_pfnGetRoleTextA == NULL)
|
|
{
|
|
// Must allocate stuff for this API call
|
|
s_pfnGetRoleTextA = (PFNrgta)GetOleAccProc("GetRoleTextA");
|
|
}
|
|
|
|
if (s_pfnGetRoleTextA)
|
|
{
|
|
if(lpszRole==NULL || cchRoleMax==0)
|
|
{
|
|
RetVal = (s_pfnGetRoleTextA(lRole, (LPSTR)NULL, 0));
|
|
}
|
|
else
|
|
{
|
|
LPSTR lpszRoleAnsi = GodotHeapAlloc(cchRoleMax * g_mcs);
|
|
|
|
if(lpszRoleAnsi==NULL)
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(0);
|
|
}
|
|
|
|
RetVal = (s_pfnGetRoleTextA(lRole, lpszRoleAnsi, cchRoleMax));
|
|
|
|
if(RetVal)
|
|
{
|
|
MultiByteToWideChar(g_acp, 0, lpszRoleAnsi, RetVal + 1, lpszRole, cchRoleMax);
|
|
RetVal = gwcslen(lpszRole);
|
|
}
|
|
|
|
GodotHeapFree(lpszRoleAnsi);
|
|
}
|
|
}
|
|
else
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetSaveFileNameW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotGetSaveFileNameW(LPOPENFILENAMEW lpofn)
|
|
{
|
|
return(GetOpenSaveFileHelper(lpofn, FALSE));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetSaveFileNamePreviewW
|
|
Begin=
|
|
BOOL __stdcall GodotGetSaveFileNamePreviewW(LPOPENFILENAMEW lpofn)
|
|
{
|
|
// ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
|
|
return(FALSE);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetShortPathNameW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotGetShortPathNameW(LPCWSTR lpszLongPath, LPWSTR lpszShortPath, DWORD cchBuffer)
|
|
{
|
|
// Begin locals
|
|
DWORD RetVal;
|
|
LPSTR lpszLongPathAnsi;
|
|
LPSTR lpszShortPathAnsi;
|
|
UINT cpg = FILES_CPG;
|
|
|
|
_STACKALLOC((cchBuffer*g_mcs)+1, lpszShortPathAnsi);
|
|
GODOT_TO_CPG_STACKALLOC(lpszLongPath, lpszLongPathAnsi, cpg, g_mcs);
|
|
|
|
RetVal=GetShortPathNameA(lpszLongPathAnsi, lpszShortPathAnsi, cchBuffer);
|
|
|
|
if(RetVal)
|
|
MultiByteToWideChar(g_acp, 0, lpszShortPathAnsi, -1, lpszShortPath, cchBuffer);
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetStartupInfoW
|
|
Begin=
|
|
void __stdcall
|
|
GodotGetStartupInfoW(LPSTARTUPINFOW lpsiW)
|
|
{
|
|
// Begin locals
|
|
STARTUPINFOA siA;
|
|
ZeroMemory(&siA, sizeof(STARTUPINFOA));
|
|
siA.lpReserved = 0;
|
|
siA.cb = sizeof(STARTUPINFOA);
|
|
|
|
// Call the 'A' version of the API
|
|
GetStartupInfoA(&siA);
|
|
|
|
// Begin postcall
|
|
lpsiW->cb = sizeof(STARTUPINFOW);
|
|
lpsiW->lpReserved = NULL;
|
|
lpsiW->dwX = siA.dwX;
|
|
lpsiW->dwY = siA.dwY;
|
|
lpsiW->dwXSize = siA.dwXSize;
|
|
lpsiW->dwYSize = siA.dwYSize;
|
|
lpsiW->dwXCountChars = siA.dwXCountChars;
|
|
lpsiW->dwYCountChars = siA.dwYCountChars;
|
|
lpsiW->dwFillAttribute = siA.dwFillAttribute;
|
|
lpsiW->dwFlags = siA.dwFlags;
|
|
lpsiW->wShowWindow = siA.wShowWindow;
|
|
lpsiW->cbReserved2 = siA.cbReserved2;
|
|
lpsiW->lpReserved2 = siA.lpReserved2;
|
|
lpsiW->hStdInput = siA.hStdInput;
|
|
lpsiW->hStdOutput = siA.hStdOutput;
|
|
lpsiW->hStdError = siA.hStdError;
|
|
|
|
// For the strings, we have to use our static buffers.
|
|
// The OS returns actual pointers to the process startup
|
|
// info, which we cannot do because that info is ANSI!
|
|
if(FSTRING_VALID(siA.lpDesktop))
|
|
{
|
|
MultiByteToWideChar(g_acp, 0, siA.lpDesktop, -1, m_wzDesktop, 256);
|
|
lpsiW->lpDesktop = m_wzDesktop;
|
|
}
|
|
if(FSTRING_VALID(siA.lpTitle))
|
|
{
|
|
MultiByteToWideChar(g_acp, 0, siA.lpTitle, -1, m_wzTitle, 256);
|
|
lpsiW->lpTitle = m_wzTitle;
|
|
}
|
|
return;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetStateTextW
|
|
Begin=
|
|
UINT __stdcall GodotGetStateTextW(DWORD lStateBit, LPWSTR lpszState, UINT cchState)
|
|
{
|
|
UINT RetVal = 0;
|
|
|
|
if (s_pfnGetStateTextA == NULL)
|
|
{
|
|
// Must allocate stuff for this API call
|
|
s_pfnGetStateTextA = (PFNgsta)GetOleAccProc("GetStateTextA");
|
|
}
|
|
|
|
if (s_pfnGetStateTextA)
|
|
{
|
|
if(lpszState==NULL)
|
|
{
|
|
RetVal = (s_pfnGetStateTextA(lStateBit, (LPSTR)lpszState, cchState));
|
|
}
|
|
else
|
|
{
|
|
LPSTR lpszStateAnsi = GodotHeapAlloc(cchState * g_mcs);
|
|
|
|
if(lpszStateAnsi==NULL)
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(0);
|
|
}
|
|
RetVal = (s_pfnGetStateTextA(lStateBit, lpszStateAnsi, cchState));
|
|
|
|
if(RetVal)
|
|
{
|
|
MultiByteToWideChar(g_acp, 0, lpszStateAnsi, RetVal + 1, lpszState, cchState);
|
|
RetVal = gwcslen(lpszState);
|
|
}
|
|
|
|
GodotHeapFree(lpszStateAnsi);
|
|
}
|
|
}
|
|
else
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetStringTypeW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotGetStringTypeW(DWORD dwInfoType, LPWSTR lpSrcStr, int cchSrc, LPWORD lpCharType)
|
|
{
|
|
// Note that we insert a LOCALE_SYSTEM_DEFAULT Locale as the "W"
|
|
// version does not have the Locale param. After all, we want to
|
|
// look like NT does, not have just a Unicode wrapper around
|
|
// the Win9x function, which would be compatible with nothing.
|
|
LCID Locale = LOCALE_SYSTEM_DEFAULT;
|
|
UINT cpg = CpgFromLocale(Locale);
|
|
UINT mcs = CbPerChOfCpg(cpg);
|
|
LPSTR lpSrcStrAnsi;
|
|
|
|
// Begin precall
|
|
GODOT_TO_CPG_STACKALLOC(lpSrcStr, lpSrcStrAnsi, cpg, mcs);
|
|
if(!lpSrcStrAnsi && lpSrcStr)
|
|
return(FALSE);
|
|
|
|
return(GetStringTypeA(Locale, dwInfoType, lpSrcStrAnsi, cchSrc, lpCharType));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetSystemDirectoryW
|
|
Begin=
|
|
UINT __stdcall
|
|
GodotGetSystemDirectoryW(LPWSTR lpBuffer, UINT uSize)
|
|
{
|
|
// Begin locals
|
|
UINT RetVal;
|
|
LPSTR lpBufferAnsi;
|
|
|
|
_STACKALLOC((uSize*g_mcs)+1, lpBufferAnsi);
|
|
if(lpBufferAnsi==NULL)
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
// Call the 'A' version of the API
|
|
RetVal=GetSystemDirectoryA(lpBufferAnsi, uSize);
|
|
|
|
// Begin postcall
|
|
if(RetVal)
|
|
MultiByteToWideChar(g_acp, 0, lpBufferAnsi, -1, lpBuffer, uSize);
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetSystemWindowsDirectoryW
|
|
Begin=
|
|
UINT __stdcall
|
|
GodotGetSystemWindowsDirectoryW(LPWSTR lpBuffer, UINT uSize)
|
|
{
|
|
// Begin locals
|
|
UINT RetVal;
|
|
LPSTR lpBufferAnsi;
|
|
|
|
_STACKALLOC((uSize*g_mcs)+1, lpBufferAnsi);
|
|
if(lpBufferAnsi==NULL)
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
// Call the 'A' version of the API. Note that there IS no
|
|
// GetSystemWindowsDirectory on Win9x. But since on a
|
|
// single user system it is the same as the old
|
|
// GetWindowsDirectory call, we can cheat very effectively.
|
|
RetVal=GetWindowsDirectoryA(lpBufferAnsi, uSize);
|
|
|
|
// Begin postcall
|
|
if(RetVal)
|
|
MultiByteToWideChar(g_acp, 0, lpBufferAnsi, -1, lpBuffer, uSize);
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetTempFileNameW
|
|
Begin=
|
|
UINT __stdcall
|
|
GodotGetTempFileNameW(LPCWSTR lpPathName, LPCWSTR lpPrefixString, UINT uUnique, LPWSTR lpTempFileName)
|
|
{
|
|
// Begin locals
|
|
UINT RetVal;
|
|
LPSTR lpPathNameAnsi;
|
|
LPSTR lpPrefixStringAnsi;
|
|
char lpTempFileNameAnsi[MAX_PATH + 1];
|
|
UINT cpg = FILES_CPG;
|
|
|
|
// Begin precall
|
|
GODOT_TO_CPG_STACKALLOC(lpPathName, lpPathNameAnsi, cpg, g_mcs);
|
|
GODOT_TO_CPG_STACKALLOC(lpPrefixString, lpPrefixStringAnsi, cpg, g_mcs);
|
|
|
|
RetVal=GetTempFileNameA(lpPathNameAnsi, lpPrefixStringAnsi, uUnique, lpTempFileNameAnsi);
|
|
|
|
if(RetVal)
|
|
MultiByteToWideChar(cpg, 0, lpTempFileNameAnsi, MAX_PATH, lpTempFileName, MAX_PATH);
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetTempPathW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotGetTempPathW(DWORD nBufferLength, LPWSTR lpBuffer)
|
|
{
|
|
DWORD RetVal;
|
|
|
|
if(nBufferLength > MAX_PATH || !FSTRING_VALID(lpBuffer))
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
RetVal = 0;
|
|
}
|
|
else
|
|
{
|
|
char lpBufferAnsi[MAX_PATH + 1];
|
|
|
|
// Call the 'A' version of the API
|
|
RetVal=GetTempPathA(nBufferLength, lpBufferAnsi);
|
|
|
|
// Begin postcall
|
|
if(RetVal)
|
|
MultiByteToWideChar(FILES_CPG, 0, lpBufferAnsi, MAX_PATH, lpBuffer, MAX_PATH);
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetTextExtentExPointW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotGetTextExtentExPointW(HDC hdc, LPCWSTR lpString, int cchString, int nMaxExtent,
|
|
LPINT lpnFit, LPINT alpDx, LPSIZE lpSize)
|
|
{
|
|
LPSTR lpStringAnsi;
|
|
UINT cpg = CpgFromHdc(hdc);
|
|
UINT mcs = CbPerChOfCpg(cpg);
|
|
|
|
GODOT_TO_CPG_STACKALLOC(lpString, lpStringAnsi, cpg, mcs);
|
|
if(lpStringAnsi==NULL)
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
return(GetTextExtentExPointA(hdc, lpStringAnsi, cchString, nMaxExtent, lpnFit, alpDx, lpSize));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetTextExtentPoint32W
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotGetTextExtentPoint32W(HDC hdc, LPCWSTR lpString, int cbString, LPSIZE lpSize)
|
|
{
|
|
// Begin locals
|
|
BOOL RetVal;
|
|
LPSTR lpStringAnsi;
|
|
size_t lpStringLength;
|
|
UINT cpg = CpgFromHdc(hdc);
|
|
UINT mcs = CbPerChOfCpg(cpg);
|
|
LPWSTR lpStringCopy;
|
|
LPWSTR lpwchT;
|
|
LPWSTR lpwchEnd;
|
|
BOOL fDefault;
|
|
|
|
lpStringCopy = GodotHeapAlloc((cbString + 1) * sizeof(WCHAR));
|
|
if(lpStringCopy==NULL)
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(FALSE);
|
|
}
|
|
lpwchT = lpStringCopy;
|
|
lpwchEnd = lpStringCopy + cbString;
|
|
|
|
// make a copy so we can muck with it
|
|
memcpy(lpStringCopy, lpString, cbString * sizeof(WCHAR));
|
|
lpStringCopy[cbString] = L'\0';
|
|
|
|
// This is a workaround for Win95 bug which causes U+00B7 character to
|
|
// be rendered improperly when using the wide API (substituting U+2219
|
|
// achieves the desired effect for some reason!)
|
|
// Note: nobuyah suggested in an MSO code review that this might be a
|
|
// perf issue?
|
|
while (lpwchT < lpwchEnd)
|
|
{
|
|
if (*lpwchT == 0x00b7)
|
|
*lpwchT = 0x2219;
|
|
lpwchT++;
|
|
}
|
|
|
|
if (FDBCS_CPG(cpg))
|
|
{
|
|
fDefault = FALSE;
|
|
if (FSTRING_VALID(lpStringCopy))
|
|
{
|
|
lpStringLength = gwcslen(lpStringCopy)+1;
|
|
_STACKALLOC(lpStringLength*mcs, lpStringAnsi);
|
|
if(lpStringAnsi==NULL)
|
|
{
|
|
GodotHeapFree(lpStringCopy);
|
|
return(FALSE);
|
|
}
|
|
WideCharToMultiByte(cpg,
|
|
WC_DEFAULTCHAR|WC_COMPOSITECHECK, // default char handling
|
|
lpStringCopy,
|
|
lpStringLength,
|
|
lpStringAnsi,
|
|
lpStringLength*mcs,
|
|
NULL,
|
|
&fDefault);
|
|
}
|
|
else
|
|
lpStringAnsi = (LPSTR)lpStringCopy;
|
|
|
|
if (fDefault)
|
|
{
|
|
// GetTextExtentPoint32W() GPFs on Win 95 FE for chars above U+00FF
|
|
// Instead use a sum of GetCharWidthW() calls, plus the difference
|
|
// between GetCharWidthW() of 'X' and GetTextExtentPoint32W of 'X'
|
|
// when we detect this case. (Stole this logic from MSO).
|
|
WCHAR wchX = L'X';
|
|
int dxp;
|
|
int dxpX;
|
|
int dxpT;
|
|
|
|
RetVal = GetTextExtentPoint32W(hdc, &wchX, 1, lpSize);
|
|
|
|
if (RetVal)
|
|
{
|
|
GodotGetCharWidthW(hdc, 'X', 'X', &dxpX);
|
|
for (dxp = 0, lpwchT = lpStringCopy; lpwchT < lpwchEnd; ++lpwchT)
|
|
{
|
|
GodotGetCharWidthW(hdc, *lpwchT, *lpwchT, &dxpT);
|
|
dxp += dxpT;
|
|
}
|
|
lpSize->cx = lpSize->cx - dxpX + dxp;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Call the 'A' version of the API
|
|
RetVal=GetTextExtentPoint32A(hdc, lpStringAnsi, cbString, lpSize);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Call the 'W' version of the API
|
|
RetVal=GetTextExtentPoint32W(hdc, lpStringCopy, cbString, lpSize);
|
|
}
|
|
|
|
// Finished
|
|
GodotHeapFree(lpStringCopy);
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetTextExtentPointW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotGetTextExtentPointW(HDC hdc, LPCWSTR lpString, int cbString, LPSIZE lpSize)
|
|
{
|
|
LPSTR lpStringAnsi;
|
|
UINT cpg;
|
|
UINT mcs;
|
|
|
|
cpg = CpgFromHdc(hdc);
|
|
mcs = CbPerChOfCpg(cpg);
|
|
|
|
GODOT_TO_CPG_STACKALLOC(lpString, lpStringAnsi, cpg, mcs);
|
|
if(lpStringAnsi==NULL)
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
return(GetTextExtentPointA(hdc, lpStringAnsi, cbString, lpSize));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetTextFaceW
|
|
Begin=
|
|
int __stdcall
|
|
GodotGetTextFaceW(HDC hdc, int nCount, LPWSTR lpFaceName)
|
|
{
|
|
// Begin locals
|
|
int RetVal;
|
|
LPSTR lpFaceNameAnsi;
|
|
|
|
_STACKALLOC((nCount*g_mcs)+1, lpFaceNameAnsi);
|
|
if(lpFaceNameAnsi==NULL)
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
// Call the 'A' version of the API
|
|
RetVal=GetTextFaceA(hdc, nCount, lpFaceNameAnsi);
|
|
|
|
// Begin postcall
|
|
if(RetVal)
|
|
MultiByteToWideChar(g_acp, 0, lpFaceNameAnsi, -1, lpFaceName, nCount);
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetTextMetricsW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotGetTextMetricsW(HDC hdc, LPTEXTMETRICW lptm)
|
|
{
|
|
// Begin locals
|
|
BOOL RetVal;
|
|
TEXTMETRICA tma;
|
|
|
|
ZeroMemory(&tma, sizeof(TEXTMETRICA));
|
|
RetVal=GetTextMetricsA(hdc, &tma);
|
|
|
|
// Begin postcall
|
|
if(RetVal)
|
|
TextMetricWfromA(lptm, &tma);
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetTimeFormatW
|
|
Begin=
|
|
int __stdcall
|
|
GodotGetTimeFormatW( LCID Locale,
|
|
DWORD dwFlags,
|
|
const SYSTEMTIME * lpTime,
|
|
LPCWSTR lpFormat,
|
|
LPWSTR lpTimeStr,
|
|
int cchTime
|
|
)
|
|
{
|
|
// Begin locals
|
|
int RetVal;
|
|
LPSTR lpFormatAnsi;
|
|
UINT cpg;
|
|
UINT mcs;
|
|
|
|
// Begin precall
|
|
if(dwFlags & LOCALE_USE_CP_ACP)
|
|
{
|
|
cpg = g_acp;
|
|
mcs = g_mcs;
|
|
}
|
|
else
|
|
{
|
|
cpg = CpgFromLocale(Locale);
|
|
mcs = CbPerChOfCpg(cpg);
|
|
}
|
|
|
|
GODOT_TO_CPG_STACKALLOC(lpFormat, lpFormatAnsi, cpg, mcs);
|
|
|
|
if (FSTRING_VALID(lpTimeStr) && (cchTime > 0))
|
|
{
|
|
LPSTR lpTimeStrAnsi;
|
|
|
|
_STACKALLOC((cchTime*mcs)+1, lpTimeStrAnsi);
|
|
ZeroMemory(lpTimeStrAnsi, (cchTime*mcs)+1);
|
|
RetVal=GetTimeFormatA(Locale, dwFlags, lpTime, lpFormatAnsi, lpTimeStrAnsi, ((cchTime+1)*mcs));
|
|
|
|
if(RetVal)
|
|
MultiByteToWideChar(cpg, 0, lpTimeStrAnsi, cchTime*mcs, lpTimeStr, cchTime);
|
|
}
|
|
else
|
|
RetVal=GetTimeFormatA(Locale, dwFlags, lpTime, lpFormatAnsi, NULL, cchTime);
|
|
|
|
if ((RetVal == 0) && lpTimeStr && 0 < cchTime)
|
|
*lpTimeStr = L'\0';
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetUserNameW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotGetUserNameW(LPWSTR lpBuffer, LPDWORD nSize)
|
|
{
|
|
// Begin locals
|
|
BOOL RetVal;
|
|
LPSTR lpBufferAnsi;
|
|
|
|
if(!nSize)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return(FALSE);
|
|
}
|
|
|
|
_STACKALLOC((*nSize * g_mcs) + 1, lpBufferAnsi);
|
|
if(lpBufferAnsi==NULL)
|
|
{
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(0);
|
|
}
|
|
ZeroMemory(lpBufferAnsi, (*nSize * g_mcs) + 1);
|
|
|
|
// Call the 'A' version of the API
|
|
RetVal=GetUserNameA(lpBufferAnsi, nSize);
|
|
|
|
// Begin postcall
|
|
if(RetVal && lpBuffer && nSize)
|
|
MultiByteToWideChar(g_acp, 0, lpBufferAnsi, -1, lpBuffer, *(nSize));
|
|
|
|
// nSize has TCHARs, which should be okay for the buffer here
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetVersionExW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotGetVersionExW(LPOSVERSIONINFOW lpVersionInformation)
|
|
{
|
|
// Begin locals
|
|
BOOL RetVal;
|
|
|
|
// Note that even if they pass a OSVERSIONINFOEXW structure, we are
|
|
// only going with the the old OSVERSIONINFO part, since the other
|
|
// stuff is not supported on Win9x
|
|
if(lpVersionInformation->dwOSVersionInfoSize < sizeof(OSVERSIONINFOW))
|
|
{
|
|
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
|
return(FALSE);
|
|
}
|
|
else
|
|
{
|
|
OSVERSIONINFOA osvia;
|
|
|
|
ZeroMemory(&osvia, sizeof(OSVERSIONINFOA));
|
|
osvia.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
|
|
RetVal=GetVersionExA(&osvia);
|
|
|
|
// Begin postcall
|
|
if(RetVal)
|
|
{
|
|
memcpy(lpVersionInformation, &osvia, (5*sizeof(DWORD)));
|
|
MultiByteToWideChar(g_acp, 0, osvia.szCSDVersion, -1, lpVersionInformation->szCSDVersion, 128);
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetVolumeInformationW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotGetVolumeInformationW( LPCWSTR lpRootPathName,
|
|
LPWSTR lpVolumeNameBuffer,
|
|
DWORD nVolumeNameSize,
|
|
LPDWORD lpVolumeSerialNumber,
|
|
LPDWORD lpMaximumComponentLength,
|
|
LPDWORD lpFileSystemFlags,
|
|
LPWSTR lpFileSystemNameBuffer,
|
|
DWORD nFileSystemNameSize
|
|
)
|
|
{
|
|
// Begin locals
|
|
BOOL RetVal;
|
|
LPSTR lpRootPathNameAnsi;
|
|
LPSTR lpVolumeNameBufferAnsi;
|
|
DWORD cbVolumeNameBuffer;
|
|
LPSTR lpFileSystemNameBufferAnsi;
|
|
DWORD cbFileSystemNameBuffer;
|
|
|
|
// Begin precall
|
|
GODOT_TO_ACP_STACKALLOC(lpRootPathName, lpRootPathNameAnsi);
|
|
|
|
if((lpVolumeNameBuffer && (nVolumeNameSize > 0)))
|
|
{
|
|
cbVolumeNameBuffer = (nVolumeNameSize*g_mcs)+1;
|
|
_STACKALLOC(cbVolumeNameBuffer, lpVolumeNameBufferAnsi);
|
|
}
|
|
else
|
|
{
|
|
cbVolumeNameBuffer = 0;
|
|
lpVolumeNameBufferAnsi = NULL;
|
|
}
|
|
|
|
if((lpFileSystemNameBuffer && (nFileSystemNameSize > 0)))
|
|
{
|
|
cbFileSystemNameBuffer = (nFileSystemNameSize*g_mcs)+1;
|
|
_STACKALLOC(cbFileSystemNameBuffer, lpFileSystemNameBufferAnsi);
|
|
}
|
|
else
|
|
{
|
|
cbFileSystemNameBuffer = 0;
|
|
lpFileSystemNameBufferAnsi = NULL;
|
|
}
|
|
|
|
// Call the 'A' version of the API
|
|
RetVal=GetVolumeInformationA( lpRootPathNameAnsi,
|
|
lpVolumeNameBufferAnsi,
|
|
cbVolumeNameBuffer,
|
|
lpVolumeSerialNumber,
|
|
lpMaximumComponentLength,
|
|
lpFileSystemFlags,
|
|
lpFileSystemNameBufferAnsi,
|
|
cbFileSystemNameBuffer
|
|
);
|
|
|
|
// Begin postcall
|
|
if(RetVal)
|
|
{
|
|
if(lpVolumeNameBufferAnsi && lpVolumeNameBuffer && nVolumeNameSize)
|
|
MultiByteToWideChar(g_acp, 0,
|
|
lpVolumeNameBufferAnsi, -1,
|
|
lpVolumeNameBuffer, nVolumeNameSize);
|
|
|
|
if(lpFileSystemNameBufferAnsi && lpFileSystemNameBuffer && nFileSystemNameSize)
|
|
MultiByteToWideChar(g_acp, 0,
|
|
lpFileSystemNameBufferAnsi, -1,
|
|
lpFileSystemNameBuffer, nFileSystemNameSize);
|
|
}
|
|
else
|
|
{
|
|
if (lpVolumeNameBuffer && (0 < nVolumeNameSize))
|
|
*lpVolumeNameBuffer = L'\0';
|
|
|
|
if (lpFileSystemNameBuffer && (0 < nFileSystemNameSize))
|
|
*lpFileSystemNameBuffer = L'\0';
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetWindowLongA
|
|
Begin=
|
|
LONG __stdcall
|
|
GodotGetWindowLongA(HWND hWnd, int nIndex)
|
|
{
|
|
return(GetWindowLongInternal(hWnd, nIndex, FALSE));
|
|
}
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetWindowLongW
|
|
Begin=
|
|
LONG __stdcall
|
|
GodotGetWindowLongW(HWND hWnd, int nIndex)
|
|
{
|
|
return(GetWindowLongInternal(hWnd, nIndex, TRUE));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetWindowModuleFileNameW
|
|
Begin=
|
|
UINT __stdcall
|
|
GodotGetWindowModuleFileNameW(HWND hwnd, LPWSTR pszFileName, UINT cchFileNameMax)
|
|
{
|
|
// Begin locals
|
|
UINT RetVal = 0;
|
|
|
|
if (s_pfnGetWindowModuleFileNameA == NULL)
|
|
{
|
|
// Must allocate stuff for this API call
|
|
s_pfnGetWindowModuleFileNameA = (PFNgwmfna)GetUserProc("GetWindowModuleFileNameA");
|
|
}
|
|
|
|
if (s_pfnGetWindowModuleFileNameA)
|
|
{
|
|
LPSTR pszFileNameAnsi;
|
|
|
|
_STACKALLOC((cchFileNameMax*g_mcs)+1, pszFileNameAnsi);
|
|
if(pszFileNameAnsi==NULL)
|
|
{
|
|
return(0);
|
|
}
|
|
RetVal = (s_pfnGetWindowModuleFileNameA(hwnd, pszFileNameAnsi, cchFileNameMax));
|
|
|
|
// Begin postcall
|
|
if(RetVal)
|
|
MultiByteToWideChar(g_acp, 0, pszFileNameAnsi, -1, pszFileName, cchFileNameMax);
|
|
}
|
|
else
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetWindowsDirectoryW
|
|
Begin=
|
|
UINT __stdcall
|
|
GodotGetWindowsDirectoryW(LPWSTR lpBuffer, UINT uSize)
|
|
{
|
|
// Begin locals
|
|
UINT RetVal;
|
|
LPSTR lpBufferAnsi;
|
|
|
|
_STACKALLOC((uSize*g_mcs)+1, lpBufferAnsi);
|
|
if(lpBufferAnsi==NULL)
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
// Call the 'A' version of the API
|
|
RetVal=GetWindowsDirectoryA(lpBufferAnsi, uSize);
|
|
|
|
// Begin postcall
|
|
if(RetVal && lpBuffer && uSize)
|
|
MultiByteToWideChar(g_acp, 0, lpBufferAnsi, -1, lpBuffer, uSize);
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetWindowTextW
|
|
Begin=
|
|
int __stdcall
|
|
GodotGetWindowTextW(HWND hWnd, LPWSTR lpString, int nMaxCount)
|
|
{
|
|
/******* Blackbox Testing results for GetWindowText Win32 API ******
|
|
(information taken from VSANSI layer comments)
|
|
|
|
TestCase lpString nMaxCount Return Value *lpString modified
|
|
======================================================================
|
|
Testing GetWindowTextW on WinNT :-
|
|
A !NULL 0 0 No
|
|
B NULL 0 0 No
|
|
C NULL !0 0 No
|
|
D !NULL !0 cch w/o \0 Yes
|
|
|
|
Testing GetWindowTextA on Win95 :-
|
|
A !NULL 0 0 Yes
|
|
B NULL 0 GPF!!
|
|
C NULL !0 GPF!!
|
|
D !NULL !0 cch w/o \0 Yes
|
|
*********************************************************************/
|
|
|
|
if(!(lpString && nMaxCount > 0))
|
|
{
|
|
// If they did not pass a buffer, then we take no chances.
|
|
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
|
return(0);
|
|
}
|
|
else
|
|
{
|
|
int RetVal;
|
|
LPSTR lpStringAnsi;
|
|
|
|
lpStringAnsi = GodotHeapAlloc((nMaxCount*g_mcs)+1);
|
|
if(lpStringAnsi==NULL)
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
ZeroMemory(lpStringAnsi, (nMaxCount*g_mcs)+1);
|
|
|
|
RetVal=GetWindowTextA(hWnd, lpStringAnsi, nMaxCount);
|
|
|
|
if(RetVal)
|
|
{
|
|
MultiByteToWideChar(g_acp, 0, lpStringAnsi, -1, lpString, nMaxCount);
|
|
RetVal = gwcslen(lpString);
|
|
lpString[nMaxCount - 1] = L'\0';
|
|
}
|
|
else
|
|
{
|
|
// On some Win9x platforms (i.e. Millenium) they will still return 0
|
|
// if the buffer is not large enough, even though PSDK docs claim
|
|
// they will just truncate. Lets mimic the NT behavior.
|
|
if((GetLastError() == ERROR_INSUFFICIENT_BUFFER) && (lpStringAnsi) && (*lpStringAnsi))
|
|
{
|
|
MultiByteToWideChar(g_acp, 0, lpStringAnsi, -1, lpString, nMaxCount);
|
|
RetVal = gwcslen(lpString);
|
|
}
|
|
else if(lpString)
|
|
{
|
|
// GetWindowText() returns 0 when you call it on a window which
|
|
// has no text (e.g. edit control without any text). It also initializes
|
|
// the buffer passed in to receive the text to "\0". So we should initialize
|
|
// the buffer passed in before returning.
|
|
*lpString = L'\0';
|
|
}
|
|
}
|
|
|
|
GodotHeapFree(lpStringAnsi);
|
|
return RetVal;
|
|
}
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GetWindowTextLengthW
|
|
Begin=
|
|
|
|
int __stdcall GodotGetWindowTextLengthW(HWND hWnd)
|
|
{
|
|
int RetVal;
|
|
|
|
RetVal=GetWindowTextLengthA(hWnd);
|
|
|
|
// Note that on DBCS Win9x, this number can be up
|
|
// to twice what the window actually contains.
|
|
if((RetVal != 0) && FDBCS_CPG(g_acp))
|
|
{
|
|
__try
|
|
{
|
|
int nMaxCountAnsi = RetVal + 1;
|
|
LPSTR lpStringAnsi;
|
|
// They might have a whole MB of text here, so lets call the
|
|
// safe version of the macro
|
|
lpStringAnsi = _alloca(nMaxCountAnsi);
|
|
|
|
// Note that we do *not* call GodotGetWindowTextW, as
|
|
// this would force an additional stack alloc on us.
|
|
if(GetWindowTextA(hWnd, lpStringAnsi, nMaxCountAnsi) > 0)
|
|
{
|
|
int nMaxCount = (RetVal + 1) * sizeof(WCHAR);
|
|
LPWSTR lpString;
|
|
lpString = _alloca(nMaxCount);
|
|
return(MultiByteToWideChar(g_acp, 0, lpStringAnsi, -1, lpString, nMaxCount));
|
|
}
|
|
}
|
|
__except( EXCEPTION_EXECUTE_HANDLER )
|
|
{
|
|
gresetstkoflw();
|
|
// We failed here; no biggee, we already picked up an
|
|
// answer from the original call.
|
|
}
|
|
|
|
// If GetWindowTextA failed we will let the retval
|
|
// stand, as we are no worse off than before.
|
|
return(RetVal);
|
|
}
|
|
return(RetVal);
|
|
}
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GlobalGetAtomNameW
|
|
Begin=
|
|
UINT __stdcall
|
|
GodotGlobalGetAtomNameW(ATOM nAtom, LPWSTR lpBuffer, int nSize)
|
|
{
|
|
// Begin locals
|
|
UINT RetVal;
|
|
LPSTR lpBufferAnsi;
|
|
|
|
_STACKALLOC((nSize*g_mcs)+1, lpBufferAnsi);
|
|
if(lpBufferAnsi==NULL)
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
// Call the 'A' version of the API
|
|
RetVal=GlobalGetAtomNameA(nAtom, lpBufferAnsi, nSize);
|
|
|
|
// Begin postcall
|
|
if(RetVal)
|
|
MultiByteToWideChar(g_acp, 0, lpBufferAnsi, -1, lpBuffer, nSize);
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=GrayStringW
|
|
Begin=
|
|
|
|
BOOL __stdcall
|
|
GodotGrayStringW( HDC hDC,
|
|
HBRUSH hBrush,
|
|
GRAYSTRINGPROC lpOutputFunc,
|
|
LPARAM lpData,
|
|
int nCount,
|
|
int X,
|
|
int Y,
|
|
int nWidth,
|
|
int nHeight
|
|
)
|
|
{
|
|
LPGODOTTLSINFO lpgti;
|
|
LPARAM lpDataAnsi;
|
|
BOOL RetVal;
|
|
UINT cpg = CpgFromHdc(hDC);
|
|
UINT mcs = CbPerChOfCpg(cpg);
|
|
|
|
if((lpOutputFunc == NULL) && ((void *)lpData == NULL))
|
|
{
|
|
// We must have at least one of these!
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return(FALSE);
|
|
}
|
|
else if(lpOutputFunc == NULL)
|
|
{
|
|
// No callback, so this is easy: one convert and off to the "A" version.
|
|
GODOT_TO_CPG_STACKALLOC(lpData, lpDataAnsi, cpg, mcs);
|
|
return(GrayStringA(hDC, hBrush, lpOutputFunc, lpDataAnsi, nCount, X, Y, nWidth, nHeight));
|
|
}
|
|
else
|
|
{
|
|
// They have a callback, so we have to use it.
|
|
if(!(lpgti = GetThreadInfoSafe(TRUE)))
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(FALSE);
|
|
}
|
|
|
|
if((lpgti->pfnGrayString &&
|
|
(lpgti->pfnGrayString != lpOutputFunc)) ||
|
|
lpgti->cGrayString >= GODOTMAXREFCOUNT)
|
|
{
|
|
// A hook is already defined
|
|
SetLastError(ERROR_INVALID_FILTER_PROC);
|
|
return(FALSE);
|
|
}
|
|
lpgti->pfnGrayString = lpOutputFunc;
|
|
lpgti->cpgGrayString = cpg;
|
|
lpgti->cGrayString++;
|
|
RetVal = GrayStringA(hDC, hBrush, &GrayStringProc, lpData, nCount, X, Y, nWidth, nHeight);
|
|
lpgti->cGrayString--;
|
|
lpgti->pfnGrayString = NULL;
|
|
return(RetVal);
|
|
}
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=InitializeSecurityContextW
|
|
Begin=
|
|
SECURITY_STATUS __stdcall
|
|
GodotInitializeSecurityContextW( PCredHandle phCredential,
|
|
PCtxtHandle phContext,
|
|
SEC_WCHAR SEC_FAR * pTargetName,
|
|
unsigned long int fContextReq,
|
|
unsigned long int Reserved1,
|
|
unsigned long int TargetDataRep,
|
|
PSecBufferDesc pInput,
|
|
unsigned long int Reserved2,
|
|
PCtxtHandle phNewContext,
|
|
PSecBufferDesc pOutput,
|
|
unsigned long int * pfContextAttr,
|
|
PTimeStamp ptsExpiry
|
|
)
|
|
{
|
|
// ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
|
|
return(SEC_E_UNSUPPORTED_FUNCTION);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=InitSecurityInterfaceW
|
|
Begin=
|
|
PSecurityFunctionTableW __stdcall GodotInitSecurityInterfaceW(void)
|
|
{
|
|
// ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
return(NULL);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=InsertMenuItemW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotInsertMenuItemW(HMENU hMenu, UINT uItem, BOOL fByPosition, LPCMENUITEMINFOW lpmiiw)
|
|
{
|
|
// Begin locals
|
|
BOOL RetVal;
|
|
MENUITEMINFOA miia;
|
|
BOOL fAlloc = MenuItemInfoAfromW(&miia, lpmiiw);
|
|
|
|
RetVal=InsertMenuItemA(hMenu, uItem, fByPosition, &miia);
|
|
|
|
if(fAlloc)
|
|
GodotHeapFree(miia.dwTypeData);
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=IsBadStringPtrW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotIsBadStringPtrW(LPCWSTR lpwz, UINT_PTR cchMax)
|
|
{
|
|
if(cchMax > 0)
|
|
{
|
|
if(lpwz == NULL)
|
|
return(TRUE);
|
|
else
|
|
{
|
|
// The function is documented as checking the smaller of the number
|
|
// of bytes covered by the specified NULL terminated UNICODE string,
|
|
// or the number of WCHARs specified by cchMax. Note that cchMax may
|
|
// be -1 (meaning "go to the string's end") but that's ok because
|
|
// the loop down below will look for the terminator.
|
|
LPCWSTR lpwzStart = lpwz;
|
|
LPCWSTR lpwzEnd = &lpwzStart[cchMax - 1];
|
|
WCHAR wch = L'\0';
|
|
|
|
_try
|
|
{
|
|
do
|
|
{
|
|
wch = *(volatile WCHAR *)lpwzStart;
|
|
lpwzStart++;
|
|
}
|
|
// back up one for the string check since we have
|
|
// already advanced.
|
|
while(wch && ((lpwzStart - 1) != lpwzEnd));
|
|
}
|
|
_except(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
//if(GetExceptionCode == EXCEPTION_ACCESS_VIOLATION)
|
|
return(TRUE);
|
|
}
|
|
}
|
|
}
|
|
|
|
// if we made it here, then the string is good
|
|
return(FALSE);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=IsCharAlphaW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotIsCharAlphaW(WCHAR ch)
|
|
{
|
|
CHAR chAnsi[] = "\0\0";
|
|
BOOL fUsedDefault = FALSE;
|
|
|
|
if (&ch != NULL)
|
|
WideCharToMultiByte(g_acp, 0, (LPWSTR)&ch, 1, (LPSTR)&chAnsi, g_mcs, NULL, &fUsedDefault);
|
|
else
|
|
return(FALSE);
|
|
|
|
if(!fUsedDefault)
|
|
return(IsCharAlphaA(*chAnsi));
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return(FALSE);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=IsCharAlphaNumericW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotIsCharAlphaNumericW(WCHAR ch)
|
|
{
|
|
CHAR chAnsi[] = "\0\0";
|
|
BOOL fUsedDefault = FALSE;
|
|
|
|
if (&ch != NULL)
|
|
WideCharToMultiByte(g_acp, 0, (LPWSTR)&ch, 1, (LPSTR)&chAnsi, 1, NULL, &fUsedDefault);
|
|
else
|
|
return(FALSE);
|
|
|
|
if(!fUsedDefault)
|
|
return(IsCharAlphaNumericA(*chAnsi));
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return(FALSE);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=IsCharLowerW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotIsCharLowerW(WCHAR ch)
|
|
{
|
|
CHAR chAnsi[] = "\0\0";
|
|
BOOL fUsedDefault = FALSE;
|
|
|
|
if (&ch != NULL)
|
|
WideCharToMultiByte(g_acp, 0, (LPWSTR)&ch, 1, (LPSTR)&chAnsi, g_mcs, NULL, &fUsedDefault);
|
|
else
|
|
return(FALSE);
|
|
|
|
if(!fUsedDefault)
|
|
return(IsCharLowerA(*chAnsi));
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return(FALSE);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=IsCharUpperW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotIsCharUpperW(WCHAR ch)
|
|
{
|
|
CHAR chAnsi[] = "\0\0";
|
|
BOOL fUsedDefault = FALSE;
|
|
|
|
if (&ch != NULL)
|
|
WideCharToMultiByte(g_acp, 0, (LPWSTR)&ch, 1, (LPSTR)&chAnsi, g_mcs, NULL, &fUsedDefault);
|
|
else
|
|
return(FALSE);
|
|
|
|
if(!fUsedDefault)
|
|
return(IsCharUpperA(*chAnsi));
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return(FALSE);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=IsClipboardFormatAvailable
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotIsClipboardFormatAvailable(UINT format)
|
|
{
|
|
BOOL RetVal = IsClipboardFormatAvailable(format);
|
|
|
|
if(!RetVal)
|
|
{
|
|
// The API failed, lets find out if our more
|
|
// intelligent opinion differs from theirs.
|
|
if(format==CF_UNICODETEXT)
|
|
{
|
|
// CF_UNICODETEXT is legal if it will take CF_TEXT
|
|
RetVal = IsClipboardFormatAvailable(CF_TEXT);
|
|
}
|
|
else if((format==CF_TEXT) || (format==CF_OEMTEXT))
|
|
{
|
|
// CF_TEXT is legal if it will take CF_UNICODETEXT
|
|
RetVal = IsClipboardFormatAvailable(CF_UNICODETEXT);
|
|
}
|
|
}
|
|
|
|
return(RetVal);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=IsDestinationReachableW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotIsDestinationReachableW(LPCWSTR lpszDestination, LPQOCINFO lpQOCInfo)
|
|
{
|
|
if (s_pfnIsDestinationReachableA == NULL)
|
|
{
|
|
// Must allocate stuff for this API call
|
|
s_pfnIsDestinationReachableA = (pfnIDRA)GetSensApiProc("IsDestinationReachableA");
|
|
}
|
|
|
|
if (s_pfnIsDestinationReachableA)
|
|
{
|
|
LPSTR lpszDestinationAnsi;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lpszDestination, lpszDestinationAnsi);
|
|
if(!lpszDestinationAnsi && lpszDestination)
|
|
return(FALSE);
|
|
|
|
return(s_pfnIsDestinationReachableA(lpszDestinationAnsi, lpQOCInfo));
|
|
}
|
|
else
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=IsTextUnicode
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotIsTextUnicode(void * lpBuffer, int cb, LPINT lpi)
|
|
{
|
|
// We need this API for our own usage, so we may as
|
|
// well give it to users as well.
|
|
return(RtlIsTextUnicode(lpBuffer, cb, (PULONG)lpi));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=IsValidCodePage
|
|
Begin=
|
|
// IsValidCodePage is wrapped for UTF-7/UTF-8 support
|
|
BOOL __stdcall
|
|
GodotIsValidCodePage(UINT CodePage)
|
|
{
|
|
// Return success for these code pages
|
|
if ((CodePage == CP_UTF7) || (CodePage == CP_UTF8))
|
|
return (TRUE);
|
|
|
|
// Return TRUE if the DLL is there
|
|
if (CodePage == CP_GB18030)
|
|
return(0 != GetGB18030Handle());
|
|
|
|
return(IsValidCodePage(CodePage));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=IsWindowUnicode
|
|
Begin=
|
|
// IsWindowUnicode wrapped since the windows we create are kinda Unicode, right? :-)
|
|
BOOL __stdcall
|
|
GodotIsWindowUnicode(HWND hWnd)
|
|
{
|
|
if (IsWindow(hWnd))
|
|
return(GetUnicodeWindowProp(hWnd));
|
|
|
|
// Not a valid window. We cannot live with the GetLastError set by
|
|
// IsWindow (ERROR_INVALID_ADDRESS) since IsWindowUnicode does
|
|
// something different
|
|
SetLastError(ERROR_INVALID_WINDOW_HANDLE);
|
|
return FALSE; // IsWindowUnicode(hWnd);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=IsDialogMessageW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotIsDialogMessageW(HWND hDlg, LPMSG lpMsg)
|
|
{
|
|
return((BOOL)GodotDispatchMessage(mtIsDialogMessage, hDlg, 0, lpMsg));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=joyGetDevCapsW
|
|
Begin=
|
|
MMRESULT __stdcall GodotjoyGetDevCapsW(UINT_PTR uJoyID, LPJOYCAPSW pjc, UINT cbjc)
|
|
{
|
|
// UNSUPPORTED FUNCTION: Documented as a failure stub
|
|
if(cbjc < sizeof(JOYCAPSW))
|
|
{
|
|
return(MMSYSERR_INVALPARAM);
|
|
}
|
|
else
|
|
{
|
|
JOYCAPSA jcA;
|
|
MMRESULT RetVal;
|
|
|
|
ZeroMemory(&jcA, sizeof(JOYCAPSA));
|
|
RetVal = joyGetDevCapsA(uJoyID, &jcA, sizeof(JOYCAPSA));
|
|
|
|
if(RetVal == MMSYSERR_NOERROR)
|
|
{
|
|
pjc->wMid = jcA.wMid;
|
|
pjc->wPid = jcA.wPid;
|
|
pjc->wXmin = jcA.wXmin;
|
|
pjc->wXmax = jcA.wXmax;
|
|
pjc->wYmin = jcA.wYmin;
|
|
pjc->wYmax = jcA.wYmax;
|
|
pjc->wZmin = jcA.wZmin;
|
|
pjc->wZmax = jcA.wZmax;
|
|
pjc->wNumButtons = jcA.wNumButtons;
|
|
pjc->wPeriodMin = jcA.wPeriodMin;
|
|
pjc->wPeriodMax = jcA.wPeriodMax;
|
|
pjc->wRmin = jcA.wRmin;
|
|
pjc->wRmax = jcA.wRmax;
|
|
pjc->wRmin = jcA.wRmin;
|
|
pjc->wUmin = jcA.wUmin;
|
|
pjc->wUmax = jcA.wUmax;
|
|
pjc->wVmin = jcA.wVmin;
|
|
pjc->wVmax = jcA.wVmax;
|
|
pjc->wCaps = jcA.wCaps;
|
|
pjc->wMaxAxes = jcA.wMaxAxes;
|
|
pjc->wNumAxes = jcA.wNumAxes;
|
|
pjc->wMaxButtons = jcA.wMaxButtons;
|
|
MultiByteToWideChar(g_acp, 0, jcA.szPname, MAXPNAMELEN, pjc->szPname, MAXPNAMELEN);
|
|
MultiByteToWideChar(g_acp, 0, jcA.szRegKey, MAXPNAMELEN, pjc->szRegKey, MAXPNAMELEN);
|
|
MultiByteToWideChar(g_acp, 0,
|
|
jcA.szOEMVxD, MAX_JOYSTICKOEMVXDNAME,
|
|
pjc->szOEMVxD, MAX_JOYSTICKOEMVXDNAME);
|
|
}
|
|
return(RetVal);
|
|
}
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=LCMapStringW
|
|
Begin=
|
|
int __stdcall
|
|
GodotLCMapStringW( LCID Locale,
|
|
DWORD dwMapFlags,
|
|
LPCWSTR lpSrcStr,
|
|
int cchSrc,
|
|
LPWSTR lpDestStr,
|
|
int cchDest
|
|
)
|
|
{
|
|
// Begin locals
|
|
int RetVal;
|
|
LPSTR lpSrcStrAnsi;
|
|
UINT cpg;
|
|
UINT mcs;
|
|
|
|
// a small head check for flags that are not supported
|
|
if (dwMapFlags & (LCMAP_SIMPLIFIED_CHINESE | LCMAP_TRADITIONAL_CHINESE | LCMAP_BYTEREV))
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return(0);
|
|
}
|
|
|
|
// Begin precall: LOCALE_USE_CP_ACP is *not* adding a feature!
|
|
if (dwMapFlags & LOCALE_USE_CP_ACP)
|
|
cpg = g_acp;
|
|
else
|
|
cpg = CpgFromLocale(Locale);
|
|
|
|
mcs = CbPerChOfCpg(cpg);
|
|
|
|
if (FSTRING_VALID(lpSrcStr))
|
|
{
|
|
if(cchSrc==-1)
|
|
{
|
|
_STACKALLOC(gwcslen(lpSrcStr) * mcs, lpSrcStrAnsi);
|
|
}
|
|
else
|
|
{
|
|
_STACKALLOC(cchSrc * mcs, lpSrcStrAnsi);
|
|
}
|
|
|
|
if(lpSrcStr && lpSrcStrAnsi)
|
|
WideCharToMultiByte(cpg, 0, lpSrcStr, cchSrc, lpSrcStrAnsi, cchSrc*mcs, NULL, NULL);
|
|
}
|
|
else
|
|
lpSrcStrAnsi = (LPSTR)lpSrcStr;
|
|
|
|
if (!(dwMapFlags & LCMAP_SORTKEY))
|
|
{
|
|
if((cchDest > 0) && (lpDestStr != NULL))
|
|
{
|
|
// Ok, we have a buffer, so lets alloc and convert
|
|
int lpDestStrLength = cchDest*mcs;
|
|
LPSTR lpDestStrAnsi;
|
|
|
|
_STACKALLOC(lpDestStrLength, lpDestStrAnsi);
|
|
if((!lpDestStrAnsi) ||
|
|
(lpSrcStr && !lpSrcStrAnsi))
|
|
{
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(0);
|
|
}
|
|
|
|
RetVal=LCMapStringA(Locale, dwMapFlags, lpSrcStrAnsi, cchSrc, lpDestStrAnsi, lpDestStrLength);
|
|
if((RetVal !=0) && (lpDestStr != NULL))
|
|
MultiByteToWideChar(cpg, 0, lpDestStrAnsi, cchDest*mcs, lpDestStr, cchDest);
|
|
}
|
|
else
|
|
// no buffer, so just get the size. Comes back in TCHARs so this should be okay
|
|
RetVal=LCMapStringA(Locale, dwMapFlags, lpSrcStrAnsi, cchSrc, NULL, 0);
|
|
}
|
|
else
|
|
{
|
|
// Sort keys, we can go into the Unicode return buffer directly
|
|
RetVal=LCMapStringA(Locale, dwMapFlags, lpSrcStrAnsi, cchSrc, (LPSTR)lpDestStr, cchDest);
|
|
|
|
}
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=LoadAcceleratorsW
|
|
Begin=
|
|
HACCEL __stdcall
|
|
GodotLoadAcceleratorsW(HINSTANCE hInstance, LPCWSTR lpTableName)
|
|
{
|
|
LPSTR lpTableNameAnsi;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lpTableName, lpTableNameAnsi);
|
|
if(!lpTableNameAnsi && lpTableName)
|
|
return(FALSE);
|
|
|
|
return(LoadAcceleratorsA(hInstance, lpTableNameAnsi));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=LoadMenuIndirectW
|
|
Begin=
|
|
HMENU __stdcall
|
|
GodotLoadMenuIndirectW(const MENUTEMPLATEW * lpMenuTemplate)
|
|
{
|
|
return(LoadMenuIndirectA(lpMenuTemplate));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=LoadStringW
|
|
Begin=
|
|
int __stdcall
|
|
GodotLoadStringW(HINSTANCE hInstance, UINT uID, LPWSTR lpBuffer, int nBufferMax)
|
|
{
|
|
// Code cribbed from module.c (same in NT and Win9x)
|
|
HANDLE hResInfo;
|
|
LPWSTR lpsz;
|
|
int cch;
|
|
|
|
cch = 0;
|
|
|
|
// Make sure the parms are valid.
|
|
if (!lpBuffer || (nBufferMax-- == 0))
|
|
return 0;
|
|
|
|
// String Tables are broken up into 16 string resources. Find the resource
|
|
// containing the string we are interested in.
|
|
if(hResInfo = FindResourceA(hInstance, (LPSTR)((LONG)(((USHORT)uID >> 4) + 1)), RT_STRING))
|
|
{
|
|
// Load the resource. Note LoadResource returns an address.
|
|
if(lpsz = LoadResource(hInstance, hResInfo))
|
|
{
|
|
_try
|
|
{
|
|
// Move past the other strings in this resource.
|
|
// (16 strings in a segment -> & 0x0F)
|
|
uID &= 0x0F;
|
|
while(TRUE)
|
|
{
|
|
cch = *(lpsz++); // PASCAL like string count
|
|
// first WCHAR is count of WCHARs
|
|
if (uID-- == 0) break;
|
|
lpsz += cch; // Step to start of next string
|
|
}
|
|
|
|
// Don't copy more than the max allowed.
|
|
if (cch > nBufferMax)
|
|
cch = nBufferMax;
|
|
|
|
gwcsncpy(lpBuffer, lpsz, cch);
|
|
}
|
|
_except(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
SetLastError( ERROR_BAD_FORMAT);
|
|
cch = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Append a NULL.
|
|
lpBuffer[cch] = 0;
|
|
|
|
return cch;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=lstrcatW
|
|
Begin=
|
|
LPWSTR __stdcall
|
|
GodotlstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
|
|
{
|
|
if (FWIN95())
|
|
return gwcscat(lpString1, lpString2);
|
|
else
|
|
return(lstrcatW(lpString1, lpString2));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=lstrcmpW
|
|
Begin=
|
|
int __stdcall
|
|
GodotlstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
|
|
{
|
|
return(CompareHelper(lpString1, lpString2, FALSE));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=lstrcmpiW
|
|
Begin=
|
|
int __stdcall
|
|
GodotlstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
|
|
{
|
|
return(CompareHelper(lpString1, lpString2, TRUE));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=lstrcpyW
|
|
Begin=
|
|
LPWSTR __stdcall
|
|
GodotlstrcpyW(LPWSTR lpString1, LPCWSTR lpString2)
|
|
{
|
|
if (FWIN95())
|
|
return gwcscpy(lpString1, lpString2);
|
|
else
|
|
return(lstrcpyW(lpString1, lpString2));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=lstrcpynW
|
|
Begin=
|
|
LPWSTR __stdcall
|
|
GodotlstrcpynW(LPWSTR lpString1, LPCWSTR lpString2, int iMaxLength)
|
|
{
|
|
LPWSTR pszReturn = gwcsncpy(lpString1, lpString2, iMaxLength);
|
|
|
|
// gwcsncpy and lstrcpy behave differently about terminating NULL
|
|
// characters. The last char in the lstrcpyn buffer always gets
|
|
// a TEXT('\0'), whereas gwcsncpy doesn't do this. Thus we must
|
|
// NULL the last char before returning (gleaned from VSANSI)
|
|
lpString1[iMaxLength-1] = TEXT('\0');
|
|
|
|
return pszReturn;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=lstrlenW
|
|
Begin=
|
|
int __stdcall
|
|
GodotlstrlenW(LPCWSTR lpString)
|
|
{
|
|
// CONSIDER: Maybe we do not need this function? Isn't it supported
|
|
// in the Unicode version on all platforms?
|
|
return gwcslen(lpString);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=MapVirtualKeyW
|
|
Begin=
|
|
UINT __stdcall
|
|
GodotMapVirtualKeyW(UINT uCode, UINT uMapType)
|
|
{
|
|
UINT RetVal;
|
|
|
|
RetVal=MapVirtualKeyA(uCode, uMapType);
|
|
|
|
if((uMapType == 2) && (RetVal != 0))
|
|
{
|
|
// RetVal is an unshifted character in the loword, as
|
|
// well as a possible diacritic in the hiword
|
|
UINT cpg = CpgFromLocale(LOWORD(GetKeyboardLayout(0)));
|
|
UINT mcs = CbPerChOfCpg(cpg);
|
|
UINT RetValT;
|
|
|
|
RetValT = RetVal;
|
|
if(!FDBCS_CPG(cpg))
|
|
{
|
|
MultiByteToWideChar(cpg, 0, (LPSTR)RetVal, 1, (LPWSTR)(LOWORD(RetValT)), 1);
|
|
if(HIWORD(RetVal))
|
|
RetValT |= (UINT)0x80000000;
|
|
}
|
|
else
|
|
{
|
|
MultiByteToWideChar(cpg, 0, (LPSTR)RetVal, 1, (LPWSTR)RetValT, 1);
|
|
}
|
|
RetVal = RetValT;
|
|
}
|
|
return(RetVal);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=MapVirtualKeyExW
|
|
Begin=
|
|
UINT __stdcall
|
|
GodotMapVirtualKeyExW(UINT uCode, UINT uMapType, HKL dwhkl)
|
|
{
|
|
UINT RetVal;
|
|
|
|
RetVal=MapVirtualKeyExA(uCode, uMapType, dwhkl);
|
|
|
|
if((uMapType == 2) && (RetVal != 0))
|
|
{
|
|
// RetVal is an unshifted character in the loword, as
|
|
// well as a possible diacritic in the hiword
|
|
UINT cpg = CpgFromLocale(LOWORD(dwhkl));
|
|
UINT mcs = CbPerChOfCpg(cpg);
|
|
UINT RetValT;
|
|
|
|
RetValT = RetVal;
|
|
if(!FDBCS_CPG(cpg))
|
|
{
|
|
MultiByteToWideChar(cpg, 0, (LPSTR)RetVal, 1, (LPWSTR)(LOWORD(RetValT)), 1);
|
|
if(HIWORD(RetVal))
|
|
RetValT |= (UINT)0x80000000;
|
|
}
|
|
else
|
|
{
|
|
MultiByteToWideChar(cpg, 0, (LPSTR)RetVal, 1, (LPWSTR)RetValT, 1);
|
|
}
|
|
RetVal = RetValT;
|
|
}
|
|
return(RetVal);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=mciGetDeviceIDW
|
|
Begin=
|
|
MCIDEVICEID __stdcall GodotmciGetDeviceIDW(LPCWSTR pszDevice)
|
|
{
|
|
LPSTR pszDeviceAnsi;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(pszDevice, pszDeviceAnsi);
|
|
if(!pszDeviceAnsi && pszDevice)
|
|
return(0);
|
|
|
|
return(mciGetDeviceIDA(pszDeviceAnsi));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=mciGetErrorStringW
|
|
Begin=
|
|
BOOL __stdcall GodotmciGetErrorStringW(MCIERROR mcierr, LPWSTR pszText, UINT cchText)
|
|
{
|
|
BOOL RetVal;
|
|
|
|
if(pszText==NULL || cchText == 0)
|
|
return(midiInGetErrorTextA(mcierr, (LPSTR)pszText, cchText));
|
|
else
|
|
{
|
|
if(MAXERRORLENGTH < cchText)
|
|
{
|
|
return(MMSYSERR_INVALPARAM);
|
|
}
|
|
else
|
|
{
|
|
char pszTextAnsi[MAXERRORLENGTH];
|
|
|
|
ZeroMemory(pszTextAnsi, MAXERRORLENGTH);
|
|
RetVal = mciGetErrorStringA(mcierr, pszTextAnsi, cchText);
|
|
if(RetVal)
|
|
MultiByteToWideChar(g_acp, 0, pszTextAnsi, -1, pszText, cchText);
|
|
return(RetVal);
|
|
}
|
|
}
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=mciSendCommandW
|
|
Begin=
|
|
|
|
MCIERROR __stdcall GodotmciSendCommandW(MCIDEVICEID mciId, UINT uMsg, DWORD_PTR dw1, DWORD_PTR dw2)
|
|
{
|
|
// ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
|
|
return(MCIERR_UNSUPPORTED_FUNCTION);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=mciSendStringW
|
|
Begin=
|
|
MCIERROR __stdcall
|
|
GodotmciSendStringW(LPCWSTR lpstrCommand, LPWSTR lpstrReturnString, UINT uReturnLength, HWND hwndCallback)
|
|
{
|
|
// UNSUPPORTED FUNCTION: Documented as a failure stub
|
|
LPSTR lpstrCommandAnsi;
|
|
MCIERROR RetVal;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lpstrCommand, lpstrCommandAnsi);
|
|
if(!lpstrCommandAnsi && lpstrCommand)
|
|
return(MCIERR_OUT_OF_MEMORY);
|
|
|
|
if(lpstrReturnString && (uReturnLength > 0))
|
|
{
|
|
LPSTR lpstrReturnStringAnsi;
|
|
|
|
_STACKALLOC(uReturnLength * g_mcs, lpstrReturnStringAnsi);
|
|
if(lpstrReturnStringAnsi==NULL)
|
|
return(MCIERR_OUT_OF_MEMORY);
|
|
ZeroMemory(lpstrReturnStringAnsi, uReturnLength * g_mcs);
|
|
|
|
RetVal = mciSendStringA(lpstrCommandAnsi, lpstrReturnStringAnsi, uReturnLength, hwndCallback);
|
|
|
|
if(RetVal == MMSYSERR_NOERROR)
|
|
MultiByteToWideChar(g_acp, 0, lpstrReturnStringAnsi, -1, lpstrReturnString, uReturnLength);
|
|
else
|
|
*lpstrReturnString = L'\0';
|
|
|
|
return(RetVal);
|
|
}
|
|
else
|
|
return(mciSendStringA(lpstrCommandAnsi, NULL, 0, hwndCallback));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=MCIWndCreateW
|
|
Begin=
|
|
HWND _cdecl GodotMCIWndCreateW(HWND hwndParent, HINSTANCE hInstance, DWORD dwStyle, LPCWSTR szFile)
|
|
{
|
|
HWND RetVal;
|
|
LPSTR szFileAnsi;
|
|
LPGODOTTLSINFO lpgti = GetThreadInfoSafe(TRUE);
|
|
|
|
if(!lpgti)
|
|
return(0);
|
|
|
|
GODOT_TO_ACP_STACKALLOC(szFile, szFileAnsi);
|
|
if(!szFileAnsi && szFile)
|
|
return(0);
|
|
|
|
INIT_WINDOW_SNIFF(lpgti->hHook);
|
|
RetVal=MCIWndCreateWA(hwndParent, hInstance, dwStyle, szFileAnsi);
|
|
TERM_WINDOW_SNIFF(lpgti->hHook);
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=MessageBoxW
|
|
Begin=
|
|
int __stdcall
|
|
GodotMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType)
|
|
{
|
|
// Code taken from the BASE depot
|
|
|
|
size_t cbAnsiText, cbAnsiCaption;
|
|
int RetVal;
|
|
LPSTR pAnsiText = NULL;
|
|
LPSTR pAnsiCaption = NULL;
|
|
|
|
if(cbAnsiText = WideCharToMultiByte(g_acp, 0, lpText, -1, 0, 0, NULL, NULL))
|
|
{
|
|
if(pAnsiText = GlobalAlloc(GMEM_FIXED, cbAnsiText))
|
|
WideCharToMultiByte(g_acp, 0, lpText, -1, pAnsiText, cbAnsiText, NULL, NULL);
|
|
else
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(0);
|
|
}
|
|
}
|
|
|
|
if(cbAnsiCaption = WideCharToMultiByte(g_acp, 0, lpCaption, -1, 0, 0, NULL, NULL))
|
|
{
|
|
if(pAnsiCaption = GlobalAlloc( GMEM_FIXED, cbAnsiCaption))
|
|
WideCharToMultiByte(g_acp, 0, lpCaption, -1, pAnsiCaption, cbAnsiCaption, NULL, NULL);
|
|
else
|
|
{
|
|
if(pAnsiText)
|
|
GlobalFree(pAnsiText);
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(0);
|
|
}
|
|
}
|
|
|
|
RetVal=MessageBoxA(hWnd, pAnsiText, pAnsiCaption, uType);
|
|
|
|
if(pAnsiText)
|
|
GlobalFree(pAnsiText);
|
|
if(pAnsiCaption)
|
|
GlobalFree(pAnsiCaption);
|
|
|
|
return(RetVal);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=MessageBoxExW
|
|
Begin=
|
|
int __stdcall
|
|
GodotMessageBoxExW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType, WORD wLanguageId)
|
|
{
|
|
// Code taken from the BASE depot
|
|
|
|
size_t cbAnsiText, cbAnsiCaption;
|
|
int RetVal;
|
|
LPSTR pAnsiText = NULL;
|
|
LPSTR pAnsiCaption = NULL;
|
|
|
|
if(cbAnsiText = WideCharToMultiByte(g_acp, 0, lpText, -1, 0, 0, NULL, NULL))
|
|
{
|
|
if(pAnsiText = GlobalAlloc(GMEM_FIXED, cbAnsiText))
|
|
WideCharToMultiByte(g_acp, 0, lpText, -1, pAnsiText, cbAnsiText, NULL, NULL);
|
|
else
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(0);
|
|
}
|
|
}
|
|
|
|
if(cbAnsiCaption = WideCharToMultiByte(g_acp, 0, lpCaption, -1, 0, 0, NULL, NULL))
|
|
{
|
|
if(pAnsiCaption = GlobalAlloc(GMEM_FIXED, cbAnsiCaption))
|
|
WideCharToMultiByte(g_acp, 0, lpCaption, -1, pAnsiCaption, cbAnsiCaption, NULL, NULL);
|
|
else
|
|
{
|
|
if(pAnsiText)
|
|
GlobalFree(pAnsiText);
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(0);
|
|
}
|
|
}
|
|
|
|
RetVal=MessageBoxExA(hWnd, pAnsiText, pAnsiCaption, uType, wLanguageId);
|
|
|
|
if(pAnsiText)
|
|
GlobalFree(pAnsiText);
|
|
if(pAnsiCaption)
|
|
GlobalFree(pAnsiCaption);
|
|
|
|
return(RetVal);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=MessageBoxIndirectW
|
|
Begin=
|
|
int __stdcall
|
|
GodotMessageBoxIndirectW(const MSGBOXPARAMSW * lpMsgBoxParams)
|
|
{
|
|
// Begin locals
|
|
int RetVal;
|
|
MSGBOXPARAMSA mpa;
|
|
|
|
// Begin precall
|
|
ZeroMemory(&mpa, sizeof(MSGBOXPARAMSA));
|
|
mpa.cbSize = lpMsgBoxParams->cbSize;
|
|
mpa.hwndOwner = lpMsgBoxParams->hwndOwner;
|
|
mpa.hInstance = lpMsgBoxParams->hInstance;
|
|
mpa.dwStyle = lpMsgBoxParams->dwStyle;
|
|
mpa.dwContextHelpId = lpMsgBoxParams->dwContextHelpId;
|
|
mpa.dwLanguageId = lpMsgBoxParams->dwLanguageId;
|
|
mpa.lpfnMsgBoxCallback = lpMsgBoxParams->lpfnMsgBoxCallback;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lpMsgBoxParams->lpszText, mpa.lpszText);
|
|
GODOT_TO_ACP_STACKALLOC(lpMsgBoxParams->lpszCaption, mpa.lpszCaption);
|
|
GODOT_TO_ACP_STACKALLOC(lpMsgBoxParams->lpszIcon, mpa.lpszIcon);
|
|
if((!mpa.lpszText && lpMsgBoxParams->lpszText) ||
|
|
(!mpa.lpszCaption && lpMsgBoxParams->lpszCaption) ||
|
|
(!mpa.lpszIcon && lpMsgBoxParams->lpszIcon))
|
|
{
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(0);
|
|
}
|
|
|
|
// Call the 'A' version of the API
|
|
RetVal=MessageBoxIndirectA(&mpa);
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=midiInGetDevCapsW
|
|
Begin=
|
|
MMRESULT __stdcall GodotmidiInGetDevCapsW(UINT_PTR uDeviceID, LPMIDIINCAPSW pmic, UINT cbmic)
|
|
{
|
|
// UNSUPPORTED FUNCTION: Documented as a failure stub
|
|
if(cbmic < sizeof(MIDIINCAPSW))
|
|
{
|
|
return(MMSYSERR_INVALPARAM);
|
|
}
|
|
else
|
|
{
|
|
MIDIINCAPSA micA;
|
|
MMRESULT RetVal;
|
|
|
|
ZeroMemory(&micA, sizeof(MIDIINCAPSA));
|
|
RetVal = midiInGetDevCapsA(uDeviceID, &micA, sizeof(MIDIINCAPSA));
|
|
|
|
if(RetVal == MMSYSERR_NOERROR)
|
|
{
|
|
pmic->wMid = micA.wMid;
|
|
pmic->wPid = micA.wPid;
|
|
pmic->vDriverVersion = micA.vDriverVersion;
|
|
pmic->dwSupport = micA.dwSupport;
|
|
MultiByteToWideChar(g_acp, 0, micA.szPname, MAXPNAMELEN, pmic->szPname, MAXPNAMELEN);
|
|
}
|
|
return(RetVal);
|
|
}
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=midiInGetErrorTextW
|
|
Begin=
|
|
MMRESULT __stdcall GodotmidiInGetErrorTextW(MMRESULT mmrError, LPWSTR pszText, UINT cchText)
|
|
{
|
|
// UNSUPPORTED FUNCTION: Documented as a failure stub
|
|
if(pszText==NULL || cchText == 0)
|
|
return(midiInGetErrorTextA(mmrError, (LPSTR)pszText, cchText));
|
|
else
|
|
{
|
|
if(MAXERRORLENGTH < cchText)
|
|
{
|
|
return(MMSYSERR_INVALPARAM);
|
|
}
|
|
else
|
|
{
|
|
char pszTextA[MAXERRORLENGTH];
|
|
MMRESULT RetVal;
|
|
|
|
ZeroMemory(pszTextA, MAXERRORLENGTH);
|
|
RetVal = midiInGetErrorTextA(mmrError, pszTextA, cchText);
|
|
if(RetVal == MMSYSERR_NOERROR)
|
|
MultiByteToWideChar(g_acp, 0, pszTextA, -1, pszText, cchText);
|
|
|
|
return(RetVal);
|
|
}
|
|
}
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=midiOutGetDevCapsW
|
|
Begin=
|
|
MMRESULT __stdcall GodotmidiOutGetDevCapsW(UINT_PTR uDeviceID, LPMIDIOUTCAPSW pmoc, UINT cbmoc)
|
|
{
|
|
// UNSUPPORTED FUNCTION: Documented as a failure stub
|
|
if(cbmoc < sizeof(MIDIOUTCAPSW))
|
|
{
|
|
return(MMSYSERR_INVALPARAM);
|
|
}
|
|
else
|
|
{
|
|
MIDIOUTCAPSA mocA;
|
|
MMRESULT RetVal;
|
|
|
|
ZeroMemory(&mocA, sizeof(MIDIOUTCAPSA));
|
|
RetVal = midiOutGetDevCapsA(uDeviceID, &mocA, sizeof(MIDIOUTCAPSA));
|
|
|
|
if(RetVal == MMSYSERR_NOERROR)
|
|
{
|
|
pmoc->wMid = mocA.wMid;
|
|
pmoc->wPid = mocA.wPid;
|
|
pmoc->vDriverVersion = mocA.vDriverVersion;
|
|
pmoc->wTechnology = mocA.wTechnology;
|
|
pmoc->wVoices = mocA.wVoices;
|
|
pmoc->wNotes = mocA.wNotes;
|
|
pmoc->wChannelMask = mocA.wChannelMask;
|
|
pmoc->dwSupport = mocA.dwSupport;
|
|
MultiByteToWideChar(g_acp, 0, mocA.szPname, MAXPNAMELEN, pmoc->szPname, MAXPNAMELEN);
|
|
}
|
|
return(RetVal);
|
|
}
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=midiOutGetErrorTextW
|
|
Begin=
|
|
MMRESULT __stdcall GodotmidiOutGetErrorTextW(MMRESULT mmrError, LPWSTR pszText, UINT cchText)
|
|
{
|
|
// UNSUPPORTED FUNCTION: Documented as a failure stub
|
|
|
|
if(pszText==NULL || cchText == 0)
|
|
return(midiOutGetErrorTextA(mmrError, (LPSTR)pszText, cchText));
|
|
else
|
|
{
|
|
if(MAXERRORLENGTH < cchText)
|
|
{
|
|
return(MMSYSERR_INVALPARAM);
|
|
}
|
|
else
|
|
{
|
|
char pszTextA[MAXERRORLENGTH];
|
|
MMRESULT RetVal;
|
|
|
|
ZeroMemory(pszTextA, MAXERRORLENGTH);
|
|
RetVal = midiOutGetErrorTextA(mmrError, pszTextA, cchText);
|
|
if(RetVal == MMSYSERR_NOERROR)
|
|
MultiByteToWideChar(g_acp, 0, pszTextA, -1, pszText, cchText);
|
|
|
|
return(RetVal);
|
|
}
|
|
}
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=mixerGetControlDetailsW
|
|
Begin=
|
|
MMRESULT __stdcall GodotmixerGetControlDetailsW(HMIXEROBJ hmxobj, LPMIXERCONTROLDETAILS pmxcd, DWORD fdwDetails)
|
|
{
|
|
// ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
|
|
return(MMSYSERR_NOTSUPPORTED);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=mixerGetDevCapsW
|
|
Begin=
|
|
MMRESULT __stdcall GodotmixerGetDevCapsW(UINT_PTR uMxId, LPMIXERCAPSW pmxcaps, UINT cbmxcaps)
|
|
{
|
|
// UNSUPPORTED FUNCTION: Documented as a failure stub
|
|
|
|
if(uMxId < sizeof(MIXERCAPSW))
|
|
{
|
|
return(MMSYSERR_INVALPARAM);
|
|
}
|
|
else
|
|
{
|
|
MIXERCAPSA mxcapsA;
|
|
MMRESULT RetVal;
|
|
|
|
ZeroMemory(&mxcapsA, sizeof(MIXERCAPSA));
|
|
RetVal = mixerGetDevCapsA(uMxId, &mxcapsA, sizeof(MIXERCAPSA));
|
|
|
|
if(RetVal == MMSYSERR_NOERROR)
|
|
{
|
|
pmxcaps->wMid = mxcapsA.wMid;
|
|
pmxcaps->wPid = mxcapsA.wPid;
|
|
pmxcaps->vDriverVersion = mxcapsA.vDriverVersion;
|
|
pmxcaps->fdwSupport = mxcapsA.fdwSupport;
|
|
pmxcaps->cDestinations = mxcapsA.cDestinations;
|
|
MultiByteToWideChar(g_acp, 0, mxcapsA.szPname, MAXPNAMELEN, pmxcaps->szPname, MAXPNAMELEN);
|
|
}
|
|
return(RetVal);
|
|
}
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=mixerGetLineControlsW
|
|
Begin=
|
|
MMRESULT __stdcall
|
|
GodotmixerGetLineControlsW(HMIXEROBJ hmxobj, LPMIXERLINECONTROLSW pmxlc, DWORD fdwControls)
|
|
{
|
|
// ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
|
|
return(MMSYSERR_NOTSUPPORTED);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=mixerGetLineInfoW
|
|
Begin=
|
|
MMRESULT __stdcall GodotmixerGetLineInfoW(HMIXEROBJ hmxobj, LPMIXERLINEW pmxl, DWORD fdwInfo)
|
|
{
|
|
// ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
|
|
return(MMSYSERR_NOTSUPPORTED);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=mmioInstallIOProcW
|
|
Begin=
|
|
LPMMIOPROC __stdcall GodotmmioInstallIOProcW(FOURCC fccIOProc, LPMMIOPROC pIOProc, DWORD dwFlags)
|
|
{
|
|
// ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
return(NULL);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=mmioRenameW
|
|
Begin=
|
|
MMRESULT __stdcall
|
|
GodotmmioRenameW(LPCWSTR pszFileName, LPCWSTR pszNewFileName, LPCMMIOINFO pmmioinfo, DWORD fdwRename)
|
|
{
|
|
// UNSUPPORTED FUNCTION: Documented as a failure stub
|
|
if((MAX_PATH < gwcslen(pszFileName)) ||
|
|
(MAX_PATH < gwcslen(pszNewFileName)))
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return(0);
|
|
}
|
|
else
|
|
{
|
|
char pszFileNameAnsi[MAX_PATH + 1];
|
|
char pszNewFileNameAnsi[MAX_PATH + 1];
|
|
|
|
WideCharToMultiByte(g_acp, 0, pszFileName, -1, pszFileNameAnsi, MAX_PATH, NULL, NULL);
|
|
WideCharToMultiByte(g_acp, 0, pszNewFileName, -1, pszNewFileNameAnsi, MAX_PATH, NULL, NULL);
|
|
return(mmioRenameA(pszFileNameAnsi, pszNewFileNameAnsi, pmmioinfo, fdwRename));
|
|
}
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=mmioOpenW
|
|
Begin=
|
|
HMMIO __stdcall GodotmmioOpenW(LPWSTR pszFileName, LPMMIOINFO pmmioinfo, DWORD fdwOpen)
|
|
{
|
|
// UNSUPPORTED FUNCTION: Documented as a failure stub
|
|
if(MAX_PATH < gwcslen(pszFileName))
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
if(pmmioinfo)
|
|
pmmioinfo->wErrorRet = MMIOERR_PATHNOTFOUND;
|
|
return(0);
|
|
}
|
|
else
|
|
{
|
|
char pszFileNameAnsi[MAX_PATH + 1];
|
|
|
|
WideCharToMultiByte(g_acp, 0, pszFileName, -1, pszFileNameAnsi, MAX_PATH, NULL, NULL);
|
|
return(mmioOpenA(pszFileNameAnsi, pmmioinfo, fdwOpen));
|
|
}
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=mmioStringToFOURCCW
|
|
Begin=
|
|
FOURCC __stdcall
|
|
GodotmmioStringToFOURCCW(LPCWSTR sz, UINT uFlags)
|
|
{
|
|
// UNSUPPORTED FUNCTION: Documented as a failure stub
|
|
LPSTR szAnsi;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(sz, szAnsi);
|
|
|
|
return(mmioStringToFOURCCA(szAnsi, uFlags));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=MoveFileW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotMoveFileW(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName)
|
|
{
|
|
if((MAX_PATH < gwcslen(lpExistingFileName)) ||
|
|
(MAX_PATH < gwcslen(lpExistingFileName)))
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return(FALSE);
|
|
}
|
|
else
|
|
{
|
|
UINT cpg = FILES_CPG;
|
|
char lpEfnA[MAX_PATH + 1];
|
|
char lpNfnA[MAX_PATH + 1];
|
|
|
|
WideCharToMultiByte(cpg, 0, lpExistingFileName, -1, lpEfnA, MAX_PATH, NULL, NULL);
|
|
WideCharToMultiByte(cpg, 0, lpNewFileName, -1, lpNfnA, MAX_PATH, NULL, NULL);
|
|
return(MoveFileA(lpEfnA, lpNfnA));
|
|
}
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=MultiByteToWideChar
|
|
Begin=
|
|
// MultiByteToWideChar is wrapped for UTF-7/UTF-8 support
|
|
int __stdcall
|
|
GodotMultiByteToWideChar( UINT CodePage,
|
|
DWORD dwFlags,
|
|
LPCSTR lpMultiByteStr,
|
|
int cbMultiByte,
|
|
LPWSTR lpWideCharStr,
|
|
int cchWideChar
|
|
)
|
|
{
|
|
UINT cpg = ((CodePage == CP_THREAD_ACP) ? g_acp : CodePage);
|
|
|
|
// See if it's a special code page value for UTF translations.
|
|
if (cpg >= NLS_CP_ALGORITHM_RANGE)
|
|
return (UTFToUnicode(cpg, dwFlags, lpMultiByteStr, cbMultiByte, lpWideCharStr, cchWideChar));
|
|
|
|
// GB 18030 specified?
|
|
if (cpg == CP_GB18030)
|
|
return(GB18030Helper(cpg,
|
|
dwFlags | NLS_CP_MBTOWC,
|
|
(LPSTR)lpMultiByteStr,
|
|
cbMultiByte,
|
|
lpWideCharStr,
|
|
cchWideChar,
|
|
NULL));
|
|
|
|
return(MultiByteToWideChar(cpg, dwFlags, lpMultiByteStr, cbMultiByte, lpWideCharStr, cchWideChar));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=MultinetGetConnectionPerformanceW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotMultinetGetConnectionPerformanceW( LPNETRESOURCEW lpnrw,
|
|
LPNETCONNECTINFOSTRUCT lpNetConnectInfoStruct
|
|
)
|
|
{
|
|
NETRESOURCEA nra;
|
|
|
|
ZeroMemory(&nra, sizeof(NETRESOURCEA));
|
|
memcpy(&nra, lpnrw, (4*sizeof(DWORD)));
|
|
GODOT_TO_ACP_STACKALLOC(lpnrw->lpLocalName, nra.lpLocalName);
|
|
GODOT_TO_ACP_STACKALLOC(lpnrw->lpRemoteName, nra.lpRemoteName);
|
|
GODOT_TO_ACP_STACKALLOC(lpnrw->lpComment, nra.lpComment);
|
|
GODOT_TO_ACP_STACKALLOC(lpnrw->lpProvider, nra.lpProvider);
|
|
return(MultinetGetConnectionPerformanceA(&nra, lpNetConnectInfoStruct));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=OemToCharW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotOemToCharW(LPCSTR lpszSrc, LPWSTR lpszDst)
|
|
{
|
|
size_t cchSrc;
|
|
|
|
// MSDN claims this function never returns FALSE. It lies (in the
|
|
// case where the buffers are identical, for example).
|
|
if ((void *)lpszSrc == (void *)lpszDst)
|
|
{
|
|
SetLastError(ERROR_INVALID_ADDRESS);
|
|
return(FALSE);
|
|
}
|
|
|
|
// Why thunk? This function is just a CP_OEM->WCHAR converter, anyway!
|
|
|
|
// Get the number of bytes in the OEM string, Unicode string should
|
|
// never be more than that
|
|
cchSrc = lstrlenA(lpszSrc);
|
|
MultiByteToWideChar(g_oemcp, MB_PRECOMPOSED | MB_USEGLYPHCHARS, lpszSrc, cchSrc, lpszDst, cchSrc);
|
|
return(TRUE);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=OemToCharBuffW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotOemToCharBuffW(LPCSTR lpszSrc, LPWSTR lpszDst, DWORD cchDstLength)
|
|
{
|
|
LPSTR pTemp;
|
|
|
|
// MSDN claims this function never returns FALSE. It lies (in the
|
|
// case where the buffers are identical, for example).
|
|
if ((void *)lpszSrc == (void *)lpszDst)
|
|
{
|
|
SetLastError(ERROR_INVALID_ADDRESS);
|
|
return(FALSE);
|
|
}
|
|
|
|
// Validate the input and output pointers (taken from the actual API)
|
|
if(IsBadReadPtr(pTemp = (LPSTR)lpszSrc, cchDstLength) ||
|
|
IsBadWritePtr(pTemp = (LPSTR)lpszDst, cchDstLength))
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return(FALSE);
|
|
}
|
|
|
|
// Why thunk? This function is just a CP_OEM->WCHAR converter, anyway!
|
|
MultiByteToWideChar(g_oemcp, 0, lpszSrc, cchDstLength, lpszDst, cchDstLength);
|
|
return(TRUE);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=OleUIAddVerbMenuW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotOleUIAddVerbMenuW( LPOLEOBJECT lpOleObj,
|
|
LPCWSTR lpszShortType,
|
|
HMENU hMenu,
|
|
UINT uPos,
|
|
UINT uIDVerbMin,
|
|
UINT uIDVerbMax,
|
|
BOOL bAddConvert,
|
|
UINT idConvert,
|
|
HMENU * lphMenu
|
|
)
|
|
{
|
|
// UNSUPPORTED FUNCTION: Documented as a failure stub
|
|
LPCSTR lpszShortTypeAnsi;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lpszShortType, (LPSTR)lpszShortTypeAnsi);
|
|
if(!lpszShortTypeAnsi && lpszShortType)
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
return(OleUIAddVerbMenuA(lpOleObj, lpszShortTypeAnsi, hMenu, uPos, uIDVerbMin,
|
|
uIDVerbMax, bAddConvert, idConvert, lphMenu));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=OleUIBusyW
|
|
Begin=
|
|
UINT __stdcall
|
|
GodotOleUIBusyW(LPOLEUIBUSYW lpoubw)
|
|
{
|
|
// UNSUPPORTED FUNCTION: Documented as a failure stub
|
|
OLEUIBUSYA ouba;
|
|
|
|
memcpy(&ouba, lpoubw, sizeof(OLEUIBUSYA));
|
|
GODOT_TO_ACP_STACKALLOC(lpoubw->lpszCaption, ouba.lpszCaption);
|
|
GODOT_TO_ACP_STACKALLOC(lpoubw->lpszTemplate, ouba.lpszTemplate);
|
|
if((!ouba.lpszCaption && lpoubw->lpszCaption) ||
|
|
(!ouba.lpszTemplate && lpoubw->lpszTemplate))
|
|
{
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(FALSE);
|
|
}
|
|
|
|
return(OleUIBusyA(&ouba));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=OleUIChangeIconW
|
|
Begin=
|
|
UINT __stdcall
|
|
GodotOleUIChangeIconW(LPOLEUICHANGEICONW lpouciw)
|
|
{
|
|
// UNSUPPORTED FUNCTION: Documented as a failure stub
|
|
OLEUICHANGEICONA oucia;
|
|
UINT RetVal = 0;
|
|
ALLOCRETURN arCaption;
|
|
ALLOCRETURN arTemplate;
|
|
|
|
memcpy(&oucia, lpouciw, sizeof(OLEUIBUSYA));
|
|
arCaption = GodotToAcpOnHeap(lpouciw->lpszCaption, &(LPSTR)oucia.lpszCaption);
|
|
arTemplate = GodotToAcpOnHeap(lpouciw->lpszTemplate, &(LPSTR)oucia.lpszTemplate);
|
|
|
|
if(arCaption != arFailed && arTemplate != arFailed)
|
|
{
|
|
if(oucia.dwFlags & CIF_USEICONEXE)
|
|
WideCharToMultiByte(g_acp,
|
|
0,
|
|
lpouciw->szIconExe,
|
|
MAX_PATH,
|
|
oucia.szIconExe,
|
|
MAX_PATH,
|
|
NULL,
|
|
NULL);
|
|
|
|
RetVal = OleUIChangeIconA(&oucia);
|
|
}
|
|
else
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
|
|
if(arCaption==arAlloc)
|
|
GodotHeapFree((LPSTR)oucia.lpszCaption);
|
|
if(arTemplate==arAlloc)
|
|
GodotHeapFree((LPSTR)oucia.lpszTemplate);
|
|
return(RetVal);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=OleUIChangeSourceW
|
|
Begin=
|
|
UINT __stdcall
|
|
GodotOleUIChangeSourceW(LPOLEUICHANGESOURCEW _noname0)
|
|
{
|
|
// ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
|
|
return(OleUIChangeSourceW(_noname0));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=OleUIConvertW
|
|
Begin=
|
|
UINT __stdcall
|
|
GodotOleUIConvertW(LPOLEUICONVERTW _noname0)
|
|
{
|
|
// ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
|
|
return(OleUIConvertW(_noname0));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=OleUIEditLinksW
|
|
Begin=
|
|
UINT __stdcall
|
|
GodotOleUIEditLinksW(LPOLEUIEDITLINKSW _noname0)
|
|
{
|
|
// ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
|
|
return(OleUIEditLinksW(_noname0));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=OleUIInsertObjectW
|
|
Begin=
|
|
UINT __stdcall
|
|
GodotOleUIInsertObjectW(LPOLEUIINSERTOBJECTW _noname0)
|
|
{
|
|
// ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
|
|
return(OleUIInsertObjectW(_noname0));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=OleUIObjectPropertiesW
|
|
Begin=
|
|
UINT __stdcall
|
|
GodotOleUIObjectPropertiesW(LPOLEUIOBJECTPROPSW _noname0)
|
|
{
|
|
// ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
|
|
return(OleUIObjectPropertiesW(_noname0));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=OleUIPasteSpecialW
|
|
Begin=
|
|
UINT __stdcall
|
|
GodotOleUIPasteSpecialW(LPOLEUIPASTESPECIALW _noname0)
|
|
{
|
|
// ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
|
|
return(OleUIPasteSpecialW(_noname0));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=OleUIPromptUserW
|
|
Begin=
|
|
int _cdecl
|
|
GodotOleUIPromptUserW(int nTemplate, HWND hwndParent, ... )
|
|
{
|
|
// ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
|
|
return(OLEUI_FALSE);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=OleUIUpdateLinksW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotOleUIUpdateLinksW(LPOLEUILINKCONTAINERW lpOleUILinkCntr, HWND hwnd, LPWSTR lpszTitle, int cLinks)
|
|
{
|
|
// ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
|
|
return(OleUIUpdateLinksW(lpOleUILinkCntr, hwnd, lpszTitle, cLinks));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=OpenPrinterW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotOpenPrinterW(LPWSTR pPrinterName, LPHANDLE phPrinter, LPPRINTER_DEFAULTSW pDefault)
|
|
{
|
|
// Begin locals
|
|
BOOL RetVal = FALSE;
|
|
LPSTR pPrinterNameAnsi = NULL;
|
|
ALLOCRETURN ar = GodotToAcpOnHeap(pPrinterName, &pPrinterNameAnsi);
|
|
|
|
if(ar==arFailed)
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(FALSE);
|
|
}
|
|
|
|
if(pDefault)
|
|
{
|
|
PRINTER_DEFAULTSA pda;
|
|
|
|
ZeroMemory(&pda, sizeof(PRINTER_DEFAULTSA));
|
|
pda.pDevMode = GodotHeapAlloc(sizeof(DEVMODEA) + pDefault->pDevMode->dmDriverExtra);
|
|
if(pda.pDevMode!=NULL)
|
|
{
|
|
ZeroMemory(pda.pDevMode, sizeof(DEVMODEA) + pDefault->pDevMode->dmDriverExtra);
|
|
DevModeAfromW(pda.pDevMode, pDefault->pDevMode);
|
|
GODOT_TO_ACP_STACKALLOC(pDefault->pDatatype, pda.pDatatype);
|
|
RetVal=OpenPrinterA(pPrinterNameAnsi, phPrinter, &pda);
|
|
GodotHeapFree(pda.pDevMode);
|
|
}
|
|
else
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
}
|
|
else
|
|
{
|
|
RetVal=OpenPrinterA(pPrinterNameAnsi, phPrinter, NULL);
|
|
}
|
|
|
|
|
|
if(ar==arAlloc)
|
|
GodotHeapFree(pPrinterNameAnsi);
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=OpenWaitableTimerW
|
|
Begin=
|
|
HANDLE __stdcall
|
|
GodotOpenWaitableTimerW(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpTimerName)
|
|
{
|
|
if (s_pfnOpenWaitableTimerA == NULL)
|
|
{
|
|
// Must allocate stuff for this API call
|
|
s_pfnOpenWaitableTimerA = (PFNowta)GetKernelProc("OpenWaitableTimerA");
|
|
}
|
|
|
|
if (s_pfnOpenWaitableTimerA)
|
|
{
|
|
LPSTR lpTimerNameAnsi;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lpTimerName, lpTimerNameAnsi);
|
|
if(!lpTimerNameAnsi && lpTimerName)
|
|
return(NULL);
|
|
|
|
return(s_pfnOpenWaitableTimerA(dwDesiredAccess, bInheritHandle, lpTimerNameAnsi));
|
|
}
|
|
else
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
// Finished
|
|
return(NULL);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=PageSetupDlgW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotPageSetupDlgW(LPPAGESETUPDLGW lppsd)
|
|
{
|
|
// Begin locals
|
|
BOOL RetVal;
|
|
PAGESETUPDLGA psdA;
|
|
LPGODOTTLSINFO lpgti;
|
|
|
|
// If we cannot get out TLS info, then we cannot proceed
|
|
if(!(lpgti = GetThreadInfoSafe(TRUE)))
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(0);
|
|
}
|
|
|
|
// Do the hooks now, if the user has them
|
|
if(((lpgti->pfnPagePaint) && (lppsd->Flags & PSD_ENABLEPAGEPAINTHOOK) && (lppsd->lpfnPagePaintHook)) ||
|
|
((lpgti->pfnPageSetup) && (lppsd->Flags & PSD_ENABLEPAGESETUPHOOK) && (lppsd->lpfnPageSetupHook)))
|
|
{
|
|
SetLastError(ERROR_INVALID_FILTER_PROC);
|
|
return(0);
|
|
}
|
|
|
|
ZeroMemory(&psdA, sizeof(PAGESETUPDLGA));
|
|
psdA.lStructSize = sizeof(PAGESETUPDLGA);
|
|
|
|
if((lppsd->Flags & PSD_RETURNDEFAULT) == 0)
|
|
{
|
|
if ((lppsd->Flags & PSD_ENABLEPAGEPAINTHOOK) && (lppsd->lpfnPagePaintHook))
|
|
lpgti->pfnPagePaint = lppsd->lpfnPagePaintHook;
|
|
psdA.lpfnPagePaintHook = &PagePaintHook;
|
|
|
|
if ((lppsd->Flags & PSD_ENABLEPAGESETUPHOOK) && (lppsd->lpfnPageSetupHook))
|
|
lpgti->pfnPageSetup = lppsd->lpfnPageSetupHook;
|
|
psdA.lpfnPageSetupHook = &PageSetupHook;
|
|
}
|
|
|
|
psdA.hwndOwner = lppsd->hwndOwner;
|
|
psdA.hDevMode = HDevModeAfromW(&(lppsd->hDevMode), TRUE);
|
|
psdA.hDevNames = HDevNamesAfromW(&(lppsd->hDevNames), TRUE);
|
|
psdA.Flags = lppsd->Flags;
|
|
psdA.ptPaperSize = lppsd->ptPaperSize;
|
|
psdA.rtMinMargin = lppsd->rtMinMargin;
|
|
psdA.rtMargin = lppsd->rtMargin;
|
|
psdA.hInstance = lppsd->hInstance;
|
|
psdA.lCustData = lppsd->lCustData;
|
|
|
|
if(lppsd->Flags & PSD_ENABLEPAGESETUPTEMPLATE)
|
|
{
|
|
GODOT_TO_ACP_STACKALLOC(lppsd->lpPageSetupTemplateName, psdA.lpPageSetupTemplateName);
|
|
}
|
|
|
|
if(lppsd->Flags & PSD_ENABLEPAGESETUPTEMPLATEHANDLE)
|
|
psdA.hPageSetupTemplate = lppsd->hPageSetupTemplate;
|
|
|
|
INIT_WINDOW_SNIFF(lpgti->hHook);
|
|
RetVal=PageSetupDlgA(&psdA);
|
|
TERM_WINDOW_SNIFF(lpgti->hHook);
|
|
|
|
if((lppsd->Flags & PSD_RETURNDEFAULT) == 0)
|
|
{
|
|
if ((lppsd->Flags & PSD_ENABLEPAGEPAINTHOOK) && (lppsd->lpfnPagePaintHook))
|
|
lpgti->pfnPagePaint = NULL;
|
|
|
|
if ((lppsd->Flags & PSD_ENABLEPAGESETUPHOOK) && (lppsd->lpfnPageSetupHook))
|
|
lpgti->pfnPageSetup = NULL;
|
|
}
|
|
|
|
// Begin postcall
|
|
if(RetVal)
|
|
{
|
|
if(lppsd->hDevMode)
|
|
GlobalFree(lppsd->hDevMode);
|
|
if(lppsd->hDevNames)
|
|
GlobalFree(lppsd->hDevNames);
|
|
lppsd->hDevMode = HDevModeWfromA(&(psdA.hDevMode), TRUE);
|
|
lppsd->hDevNames = HDevNamesWfromA(&(psdA.hDevNames), TRUE);
|
|
lppsd->Flags = psdA.Flags;
|
|
lppsd->ptPaperSize = psdA.ptPaperSize;
|
|
lppsd->rtMinMargin = psdA.rtMinMargin;
|
|
lppsd->rtMargin = psdA.rtMargin;
|
|
lppsd->lCustData = psdA.lCustData;
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=PeekMessageW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotPeekMessageW(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg)
|
|
{
|
|
return(GodotReceiveMessage(mtPeekMessage, lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=PlaySoundW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotPlaySoundW(LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound)
|
|
{
|
|
BOOL RetVal;
|
|
LPSTR pszSoundAnsi;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(pszSound, pszSoundAnsi);
|
|
|
|
RetVal=PlaySoundA(pszSoundAnsi, hmod, fdwSound);
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=PolyTextOutW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotPolyTextOutW(HDC hdc, const POLYTEXTW * pptxt, int cStrings)
|
|
{
|
|
POLYTEXTA * pptxta;
|
|
int i;
|
|
size_t cchMax = 0;
|
|
size_t cchT;
|
|
UINT cpg = CpgFromHdc(hdc);
|
|
UINT mcs = CbPerChOfCpg(cpg);
|
|
LPSTR lpszBuf;
|
|
BOOL RetVal;
|
|
|
|
_STACKALLOC(sizeof(POLYTEXTA)*cStrings, pptxta);
|
|
if(pptxta==NULL)
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
for (i = 0; i<cStrings; i++ )
|
|
{
|
|
cchT = gwcslen(pptxt[i].lpstr);
|
|
cchMax += (cchT + (cchT ? 1 : 0));
|
|
}
|
|
|
|
if(!(lpszBuf = GodotHeapAlloc(cchMax * mcs)))
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(FALSE);
|
|
}
|
|
|
|
// Reset some vars
|
|
cchT = 0;
|
|
cchMax = 0;
|
|
|
|
ZeroMemory(pptxta, (sizeof(POLYTEXTA)*cStrings));
|
|
for (i = 0; i<cStrings; i++ )
|
|
{
|
|
pptxta[i].x = pptxt[i].x;
|
|
pptxta[i].y = pptxt[i].y;
|
|
pptxta[i].n = pptxt[i].n;
|
|
pptxta[i].uiFlags = pptxt[i].uiFlags;
|
|
pptxta[i].rcl = pptxt[i].rcl;
|
|
pptxta[i].pdx = pptxt[i].pdx;
|
|
if(FSTRING_VALID(pptxt[i].lpstr))
|
|
{
|
|
cchT = gwcslen(pptxt[i].lpstr);
|
|
pptxta[i].lpstr = (LPSTR)lpszBuf + cchMax;
|
|
WideCharToMultiByte(cpg, 0,
|
|
pptxt[i].lpstr, cchT,
|
|
(LPSTR)pptxta[i].lpstr, (cchT * mcs),
|
|
NULL, NULL);
|
|
cchMax += (cchT * mcs);
|
|
}
|
|
else
|
|
pptxta[i].lpstr = (LPSTR)pptxt[i].lpstr;
|
|
}
|
|
|
|
// Call the 'A' version of the API
|
|
RetVal = PolyTextOutA(hdc, pptxta, cStrings);
|
|
|
|
if(lpszBuf)
|
|
GodotHeapFree(lpszBuf);
|
|
return(RetVal);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=PostMessageW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotPostMessageW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
return((BOOL)GodotTransmitMessage(mtPostMessage, hWnd, Msg, wParam, lParam, 0, 0, 0, 0, 0, 0));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=PostThreadMessageW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotPostThreadMessageW(DWORD idThread, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
return((BOOL)GodotTransmitMessage(mtPostThreadMessage, (HWND)idThread, Msg, wParam,
|
|
lParam, 0, 0, 0, 0, 0, 0));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=PrintDlgW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotPrintDlgW(LPPRINTDLGW lppd)
|
|
{
|
|
// Begin locals
|
|
BOOL RetVal;
|
|
PRINTDLGA pdA;
|
|
LPGODOTTLSINFO lpgti;
|
|
|
|
// If we cannot get out TLS info, then we cannot proceed
|
|
if(!(lpgti = GetThreadInfoSafe(TRUE)))
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(0);
|
|
}
|
|
|
|
// Do the hooks now, if the user has them
|
|
if(((lpgti->pfnPrintDlg) && (lppd->Flags & PD_ENABLEPRINTHOOK) && (lppd->lpfnPrintHook)) ||
|
|
((lpgti->pfnPrintDlgSetup) && (lppd->Flags & PD_ENABLESETUPHOOK) && (lppd->lpfnSetupHook)))
|
|
{
|
|
SetLastError(ERROR_INVALID_FILTER_PROC);
|
|
return(0);
|
|
}
|
|
|
|
ZeroMemory(&pdA, sizeof(PRINTDLGA));
|
|
pdA.lStructSize = sizeof(PRINTDLGA);
|
|
|
|
pdA.Flags = lppd->Flags;
|
|
|
|
if((lppd->Flags & PD_RETURNDEFAULT) == 0)
|
|
{
|
|
if ((lppd->Flags & PD_ENABLEPRINTHOOK) && (lppd->lpfnPrintHook))
|
|
lpgti->pfnPrintDlg = lppd->lpfnPrintHook;
|
|
pdA.lpfnPrintHook = &PrintHookProc;
|
|
pdA.Flags |= PD_ENABLEPRINTHOOK;
|
|
|
|
if ((lppd->Flags & PD_ENABLESETUPHOOK) && (lppd->lpfnSetupHook))
|
|
lpgti->pfnPrintDlgSetup = lppd->lpfnSetupHook;
|
|
pdA.lpfnSetupHook = &SetupHookProc;
|
|
pdA.Flags |= PD_ENABLESETUPHOOK;
|
|
}
|
|
|
|
pdA.hwndOwner = lppd->hwndOwner;
|
|
pdA.hDevMode = HDevModeAfromW(&(lppd->hDevMode), FALSE);
|
|
pdA.hDevNames = HDevNamesAfromW(&(lppd->hDevNames), FALSE);
|
|
pdA.hDC = lppd->hDC;
|
|
pdA.nFromPage = lppd->nFromPage;
|
|
pdA.nToPage = lppd->nToPage;
|
|
pdA.nMinPage = lppd->nMinPage;
|
|
pdA.nMaxPage = lppd->nMaxPage;
|
|
pdA.nCopies = lppd->nCopies;
|
|
pdA.hInstance = lppd->hInstance;
|
|
pdA.lCustData = lppd->lCustData;
|
|
|
|
if(lppd->Flags & PD_ENABLEPRINTTEMPLATE)
|
|
{
|
|
GODOT_TO_ACP_STACKALLOC(lppd->lpPrintTemplateName, pdA.lpPrintTemplateName);
|
|
}
|
|
|
|
if(lppd->Flags & PD_ENABLESETUPTEMPLATE)
|
|
{
|
|
GODOT_TO_ACP_STACKALLOC(lppd->lpSetupTemplateName, pdA.lpSetupTemplateName);
|
|
}
|
|
|
|
if(lppd->Flags & PD_ENABLEPRINTTEMPLATEHANDLE)
|
|
pdA.hPrintTemplate = lppd->hPrintTemplate;
|
|
|
|
if(lppd->Flags & PD_ENABLESETUPTEMPLATEHANDLE)
|
|
pdA.hSetupTemplate = lppd->hSetupTemplate;
|
|
|
|
INIT_WINDOW_SNIFF(lpgti->hHook);
|
|
RetVal=PrintDlgA(&pdA);
|
|
TERM_WINDOW_SNIFF(lpgti->hHook);
|
|
|
|
if((lppd->Flags & PD_RETURNDEFAULT) == 0)
|
|
{
|
|
if ((lppd->Flags & PD_ENABLEPRINTHOOK) && (lppd->lpfnPrintHook))
|
|
lpgti->pfnPrintDlg = NULL;
|
|
|
|
if ((lppd->Flags & PD_ENABLESETUPHOOK) && (lppd->lpfnSetupHook))
|
|
lpgti->pfnPrintDlgSetup = NULL;
|
|
}
|
|
|
|
// Begin postcall
|
|
if(RetVal)
|
|
{
|
|
if(lppd->hDevMode)
|
|
GlobalFree(lppd->hDevMode);
|
|
if(lppd->hDevNames)
|
|
GlobalFree(lppd->hDevNames);
|
|
lppd->hDevMode = HDevModeWfromA(&(pdA.hDevMode), TRUE);
|
|
lppd->hDevNames = HDevNamesWfromA(&(pdA.hDevNames), TRUE);
|
|
lppd->hDC = pdA.hDC;
|
|
lppd->Flags = pdA.Flags;
|
|
lppd->nFromPage = pdA.nFromPage;
|
|
lppd->nToPage = pdA.nToPage;
|
|
lppd->nMinPage = pdA.nMinPage;
|
|
lppd->nMaxPage = pdA.nMaxPage;
|
|
lppd->nCopies = pdA.nCopies;
|
|
lppd->lCustData = pdA.lCustData;
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=QueryContextAttributesW
|
|
Begin=
|
|
SECURITY_STATUS __stdcall
|
|
GodotQueryContextAttributesW(PCtxtHandle phContext, unsigned long int ulAttribute, void * pBuffer)
|
|
{
|
|
// ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
|
|
return(SEC_E_UNSUPPORTED_FUNCTION);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=QueryCredentialsAttributesW
|
|
Begin=
|
|
SECURITY_STATUS __stdcall
|
|
GodotQueryCredentialsAttributesW(PCredHandle phCredential, unsigned long int ulAttribute, void * pBuffer)
|
|
{
|
|
// ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
|
|
return(SEC_E_UNSUPPORTED_FUNCTION);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=QueryDosDeviceW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotQueryDosDeviceW(LPCWSTR lpDeviceName, LPWSTR lpTargetPath, DWORD ucchMax)
|
|
{
|
|
DWORD RetVal;
|
|
LPSTR lpDeviceNameAnsi;
|
|
LPSTR lpTargetPathAnsi;
|
|
UINT cpg = FILES_CPG;
|
|
|
|
_STACKALLOC((ucchMax*g_mcs)+1, lpTargetPathAnsi);
|
|
GODOT_TO_CPG_STACKALLOC(lpDeviceName, lpDeviceNameAnsi, cpg, g_mcs);
|
|
|
|
RetVal=QueryDosDeviceA(lpDeviceNameAnsi, lpTargetPathAnsi, ucchMax);
|
|
|
|
if(RetVal)
|
|
MultiByteToWideChar(g_acp, 0, lpTargetPathAnsi, -1, lpTargetPath, ucchMax);
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=QuerySecurityPackageInfoW
|
|
Begin=
|
|
SECURITY_STATUS __stdcall
|
|
GodotQuerySecurityPackageInfoW(SEC_WCHAR SEC_FAR * pPackageName, PSecPkgInfoW * ppPackageInfo)
|
|
{
|
|
// ACTUAL FAILURE STUB; USER CAN OVERRIDE IF THEY WANT TO
|
|
return(SEC_E_UNSUPPORTED_FUNCTION);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=RasConnectionNotificationW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotRasConnectionNotificationW(HRASCONN hrasconn, HANDLE hEvent, DWORD dwFlags)
|
|
{
|
|
// if the call fails due to it not being on the OS (say like on
|
|
// win95), then it might return a "non-zero" error
|
|
// code, rather than using SetLastError. Godot will do both.
|
|
DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
|
|
|
|
if (s_pfnRasConnectionNotificationA == NULL)
|
|
s_pfnRasConnectionNotificationA = (pfnRCN)GetRasProc("RasConnectionNotificationA");
|
|
|
|
if (s_pfnRasConnectionNotificationA)
|
|
{
|
|
// Why the heck is this function A/W decorated, anyway?
|
|
// Its not like there are any strings here!
|
|
RetVal=(s_pfnRasConnectionNotificationA(hrasconn, hEvent, dwFlags));
|
|
}
|
|
else
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=RasCreatePhonebookEntryW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotRasCreatePhonebookEntryW(HWND hwnd, LPCWSTR lpszPhonebook)
|
|
{
|
|
// if the call fails due to it not being on the OS (say like on
|
|
// win95), then it might return a "non-zero" error
|
|
// code, rather than using SetLastError. Godot will do both.
|
|
DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
|
|
|
|
if (s_pfnRasCreatePhonebookEntryA == NULL)
|
|
s_pfnRasCreatePhonebookEntryA = (pfnRCPE)GetRasProc("RasCreatePhonebookEntryA");
|
|
|
|
if (s_pfnRasCreatePhonebookEntryA)
|
|
{
|
|
if(MAX_PATH < gwcslen(lpszPhonebook))
|
|
RetVal = ERROR_INVALID_PARAMETER;
|
|
else
|
|
{
|
|
char lpszPhonebookAnsi[MAX_PATH + 1];
|
|
|
|
WideCharToMultiByte(g_acp, 0, lpszPhonebook, -1, lpszPhonebookAnsi, MAX_PATH, NULL, NULL);
|
|
RetVal=(s_pfnRasCreatePhonebookEntryA(hwnd, lpszPhonebookAnsi));
|
|
}
|
|
}
|
|
|
|
// Finished
|
|
return(RetVal);
|
|
UNREFERENCED_PARAMETER(lpszPhonebook);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=RasDeleteEntryW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotRasDeleteEntryW(LPCWSTR lpszPhonebook, LPCWSTR lpszEntry)
|
|
{
|
|
// if the call fails due to it not being on the OS (say like on
|
|
// win95), then it might return a "non-zero" error
|
|
// code, rather than using SetLastError. Godot will do both.
|
|
DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
|
|
|
|
if (s_pfnRasDeleteEntryA == NULL)
|
|
s_pfnRasDeleteEntryA = (pfnRDE)GetRasProc("RasDeleteEntryA");
|
|
|
|
if (s_pfnRasDeleteEntryA)
|
|
{
|
|
if(RAS_MaxEntryName < gwcslen(lpszEntry))
|
|
RetVal = ERROR_INVALID_PARAMETER;
|
|
else
|
|
{
|
|
char lpszEntryAnsi[RAS_MaxEntryName + 1];
|
|
|
|
WideCharToMultiByte(g_acp, 0, lpszEntry, -1, lpszEntryAnsi, RAS_MaxEntryName, NULL, NULL);
|
|
RetVal=(s_pfnRasDeleteEntryA(NULL, lpszEntryAnsi));
|
|
}
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
UNREFERENCED_PARAMETER(lpszPhonebook);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=RasDeleteSubEntryW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotRasDeleteSubEntryW(LPCWSTR pszPhonebook, LPCWSTR pszEntry, DWORD dwSubEntryId)
|
|
{
|
|
// if the call fails due to it not being on the OS (say like on
|
|
// win95 or Win98), then it might return a "non-zero" error
|
|
// code, rather than using SetLastError. Godot will do both.
|
|
DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
|
|
|
|
if (s_pfnRasDeleteSubEntryA == NULL)
|
|
s_pfnRasDeleteSubEntryA = (pfnRDSE)GetRasProc("RasDeleteSubEntryA");
|
|
|
|
if (s_pfnRasDeleteSubEntryA)
|
|
{
|
|
CHAR pszEntryAnsi[RAS_MaxEntryName + 1];
|
|
int cch = WideCharToMultiByte(g_acp, 0, pszEntry, -1, pszEntryAnsi, RAS_MaxEntryName, NULL, NULL);
|
|
|
|
if(cch && (RAS_MaxEntryName >= cch))
|
|
RetVal=(s_pfnRasDeleteSubEntryA(NULL, pszEntryAnsi, dwSubEntryId));
|
|
else
|
|
RetVal = ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
UNREFERENCED_PARAMETER(pszPhonebook);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=RasDialW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotRasDialW( LPRASDIALEXTENSIONS lpRasDialExtensions,
|
|
LPCWSTR lpszPhonebook,
|
|
LPRASDIALPARAMSW lpRasDialParams,
|
|
DWORD dwNotifierType,
|
|
LPVOID lpvNotifier,
|
|
LPHRASCONN lphRasConn
|
|
)
|
|
{
|
|
// if the call fails due to it not being on the OS (say like on
|
|
// win95), then it might return a "non-zero" error
|
|
// code, rather than using SetLastError. Godot will do both.
|
|
DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
|
|
|
|
if (s_pfnRasDialA == NULL)
|
|
s_pfnRasDialA = (pfnRD)GetRasProc("RasDialA");
|
|
|
|
if (s_pfnRasDialA)
|
|
{
|
|
// Per the PSDK, lpRasDialExtensions and
|
|
// lpszPhonebook are ignored on Win9x
|
|
RASDIALPARAMSA rdpa;
|
|
|
|
ZeroMemory(&rdpa, sizeof(RASDIALPARAMSA));
|
|
rdpa.dwSize = sizeof(RASDIALPARAMSA);
|
|
WideCharToMultiByte(g_acp, 0, lpRasDialParams->szEntryName, RAS_MaxEntryName, rdpa.szEntryName, RAS_MaxEntryName, NULL, NULL);
|
|
WideCharToMultiByte(g_acp, 0, lpRasDialParams->szPhoneNumber, RAS_MaxPhoneNumber, rdpa.szPhoneNumber, RAS_MaxPhoneNumber, NULL, NULL);
|
|
WideCharToMultiByte(g_acp, 0, lpRasDialParams->szCallbackNumber, RAS_MaxCallbackNumber, rdpa.szCallbackNumber, RAS_MaxCallbackNumber, NULL, NULL);
|
|
WideCharToMultiByte(g_acp, 0, lpRasDialParams->szUserName, UNLEN, rdpa.szUserName, UNLEN, NULL, NULL);
|
|
WideCharToMultiByte(g_acp, 0, lpRasDialParams->szPassword, PWLEN, rdpa.szPassword, PWLEN, NULL, NULL);
|
|
WideCharToMultiByte(g_acp, 0, lpRasDialParams->szDomain, DNLEN, rdpa.szDomain, RAS_MaxEntryName, NULL, NULL);
|
|
|
|
// Do not copy lprdpa->dwSubEntry or dwCallbackId, even if they are
|
|
// present, as they are Win2000 only members
|
|
|
|
RetVal=(s_pfnRasDialA(NULL, NULL, &rdpa, dwNotifierType, lpvNotifier, lphRasConn));
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
UNREFERENCED_PARAMETER(lpszPhonebook);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=RasEditPhonebookEntryW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotRasEditPhonebookEntryW(HWND hwnd, LPCWSTR lpszPhonebook, LPCWSTR lpszEntryName)
|
|
{
|
|
// if the call fails due to it not being on the OS (say like on
|
|
// win95), then it might return a "non-zero" error
|
|
// code, rather than using SetLastError. Godot will do both.
|
|
DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
|
|
|
|
if (s_pfnRasEditPhonebookEntryA == NULL)
|
|
s_pfnRasEditPhonebookEntryA = (pfnREPE)GetRasProc("RasEditPhonebookEntryA");
|
|
|
|
if (s_pfnRasEditPhonebookEntryA)
|
|
{
|
|
if(RAS_MaxEntryName < gwcslen(lpszEntryName))
|
|
RetVal = ERROR_INVALID_PARAMETER;
|
|
else
|
|
{
|
|
char lpszEntryNameAnsi[RAS_MaxEntryName];
|
|
|
|
WideCharToMultiByte(g_acp, 0, lpszEntryName, -1, lpszEntryNameAnsi, RAS_MaxEntryName, NULL, NULL);
|
|
RetVal=(s_pfnRasEditPhonebookEntryA(hwnd, NULL, lpszEntryNameAnsi));
|
|
}
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
UNREFERENCED_PARAMETER(lpszPhonebook);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=RasEnumConnectionsW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotRasEnumConnectionsW(struct tagRASCONNW * lprasconn, LPDWORD lpcb, LPDWORD lpcConnections)
|
|
{
|
|
// if the call fails due to it not being on the OS (say like on
|
|
// win95), then it might return a "non-zero" error
|
|
// code, rather than using SetLastError. Godot will do both.
|
|
DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
|
|
|
|
if (s_pfnRasEnumConnectionsA == NULL)
|
|
s_pfnRasEnumConnectionsA = (pfnREC)GetRasProc("RasEnumConnectionsA");
|
|
|
|
if (s_pfnRasEnumConnectionsA)
|
|
{
|
|
BOOL fNew;
|
|
DWORD cbConnections;
|
|
LPRASCONNA lprasconnA;
|
|
|
|
// Check parameters.
|
|
if (!lprasconn || (lprasconn->dwSize < CBRASCONNOLDW))
|
|
return ERROR_INVALID_SIZE;
|
|
|
|
if (lpcb == NULL || lpcConnections == NULL)
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
if(fNew = (lprasconn->dwSize == CBRASCONNOLDW))
|
|
{
|
|
cbConnections = CBRASCONNOLDA * (*lpcb / CBRASCONNOLDW);
|
|
_STACKALLOC(cbConnections, lprasconnA);
|
|
ZeroMemory(lprasconnA, cbConnections);
|
|
lprasconnA->dwSize = CBRASCONNOLDA;
|
|
}
|
|
else
|
|
{
|
|
cbConnections = CBRASCONNNEWA * (*lpcb / CBRASCONNNEWW);
|
|
_STACKALLOC(cbConnections, lprasconnA);
|
|
ZeroMemory(lprasconnA, cbConnections);
|
|
lprasconnA->dwSize = CBRASCONNNEWA;
|
|
}
|
|
|
|
RetVal=(s_pfnRasEnumConnectionsA(lprasconnA, &cbConnections, lpcConnections));
|
|
|
|
// If the call succeeded, copy data back to the caller's buffer
|
|
if(RetVal==0)
|
|
{
|
|
DWORD iCon;
|
|
|
|
for(iCon = 0 ; iCon < *lpcConnections ; iCon++)
|
|
{
|
|
LPRASCONNW lprcw = &lprasconn[iCon];
|
|
LPRASCONNA lprca = &lprasconnA[iCon];
|
|
|
|
lprcw->hrasconn = lprca->hrasconn;
|
|
MultiByteToWideChar(g_acp, 0,
|
|
lprca->szEntryName, RAS_MaxEntryName,
|
|
lprcw->szEntryName, RAS_MaxEntryName);
|
|
MultiByteToWideChar(g_acp, 0,
|
|
lprca->szDeviceType, RAS_MaxDeviceType,
|
|
lprcw->szDeviceType, RAS_MaxDeviceType);
|
|
MultiByteToWideChar(g_acp, 0,
|
|
lprca->szDeviceName, RAS_MaxDeviceName,
|
|
lprcw->szDeviceName, RAS_MaxDeviceName);
|
|
|
|
if(!fNew)
|
|
{
|
|
lprcw->dwSize = CBRASCONNOLDW;
|
|
}
|
|
else
|
|
{
|
|
lprcw->dwSize = CBRASCONNNEWW;
|
|
lprcw->dwSubEntry = lprca->dwSubEntry;
|
|
MultiByteToWideChar(g_acp, 0,
|
|
lprca->szPhonebook, MAX_PATH,
|
|
lprcw->szPhonebook, MAX_PATH);
|
|
}
|
|
}
|
|
}
|
|
|
|
// In all cases, *lpcb should be updated
|
|
// with the correct size.
|
|
*lpcb = (*lpcConnections * lprasconn->dwSize);
|
|
}
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=RasEnumDevicesW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotRasEnumDevicesW(LPRASDEVINFOW lpRasDevInfo, LPDWORD lpcb, LPDWORD lpcDevices)
|
|
{
|
|
// if the call fails due to it not being on the OS (say like on
|
|
// win95), then it might return a "non-zero" error
|
|
// code, rather than using SetLastError. Godot will do both.
|
|
DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
|
|
|
|
if (s_pfnRasEnumDevicesA == NULL)
|
|
s_pfnRasEnumDevicesA = (pfnRED)GetRasProc("RasEnumDevicesA");
|
|
|
|
if (s_pfnRasEnumDevicesA)
|
|
{
|
|
UINT i;
|
|
DWORD cbAnsi = *lpcb;
|
|
|
|
if (lpRasDevInfo == NULL || cbAnsi == 0)
|
|
RetVal=(s_pfnRasEnumDevicesA(NULL, &cbAnsi, lpcDevices));
|
|
else
|
|
{
|
|
LPRASDEVINFOA lprdia;
|
|
_STACKALLOC(*lpcDevices * sizeof(RASDEVINFOA), lprdia);
|
|
if(lprdia==NULL)
|
|
return(ERROR_STACK_OVERFLOW);
|
|
|
|
lprdia->dwSize = sizeof(RASDEVINFOA);
|
|
RetVal=(s_pfnRasEnumDevicesA(lprdia, &cbAnsi, lpcDevices));
|
|
if(RetVal == 0)
|
|
{
|
|
for (i=0; i < *(lpcDevices); i++)
|
|
{
|
|
MultiByteToWideChar(g_acp,
|
|
0,
|
|
lprdia[i].szDeviceType,
|
|
RAS_MaxDeviceType,
|
|
lpRasDevInfo[i].szDeviceType,
|
|
RAS_MaxDeviceType);
|
|
MultiByteToWideChar(g_acp,
|
|
0,
|
|
lprdia[i].szDeviceName,
|
|
RAS_MaxDeviceName,
|
|
lpRasDevInfo[i].szDeviceName,
|
|
RAS_MaxDeviceName);
|
|
}
|
|
}
|
|
}
|
|
*lpcb = ((cbAnsi)/sizeof(RASDEVINFOA))*sizeof(RASDEVINFOW);
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=RasEnumEntriesW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotRasEnumEntriesW( LPCWSTR reserved,
|
|
LPCWSTR lpszPhonebook,
|
|
LPRASENTRYNAMEW lprasentryname,
|
|
LPDWORD lpcb,
|
|
LPDWORD lpcEntries
|
|
)
|
|
{
|
|
// if the call fails due to it not being on the OS (say like on
|
|
// win95), then it might return a "non-zero" error
|
|
// code, rather than using SetLastError. Godot will do both.
|
|
DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
|
|
|
|
if (s_pfnRasEnumEntriesA == NULL)
|
|
s_pfnRasEnumEntriesA = (pfnREE)GetRasProc("RasEnumEntriesA");
|
|
|
|
if (s_pfnRasEnumEntriesA)
|
|
{
|
|
DWORD cbAnsi = *lpcb;
|
|
LPRASENTRYNAMEA lprena;
|
|
UINT i;
|
|
|
|
_STACKALLOC(cbAnsi * sizeof(RASENTRYNAMEA), lprena);
|
|
if(lprena==NULL)
|
|
return(ERROR_STACK_OVERFLOW);
|
|
|
|
lprena->dwSize = sizeof(RASENTRYNAMEA);
|
|
|
|
// Calling RasEnumEntries to enumerate the phone-book entries
|
|
RetVal = (s_pfnRasEnumEntriesA(NULL, NULL, lprena, &cbAnsi, lpcEntries));
|
|
|
|
if(RetVal == 0)
|
|
{
|
|
for (i=0; i < *(lpcEntries); i++)
|
|
{
|
|
MultiByteToWideChar(g_acp,
|
|
0,
|
|
lprena[i].szEntryName,
|
|
RAS_MaxEntryName,
|
|
lprasentryname[i].szEntryName,
|
|
RAS_MaxEntryName);
|
|
lprena++;
|
|
lprasentryname++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
*lpcb = cbAnsi*sizeof(WCHAR);
|
|
}
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
UNREFERENCED_PARAMETER(lpszPhonebook);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=RasGetConnectStatusW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotRasGetConnectStatusW(HRASCONN hrasconn, LPRASCONNSTATUSW lprasconnstatus)
|
|
{
|
|
// if the call fails due to it not being on the OS (say like on
|
|
// win95), then it might return a "non-zero" error
|
|
// code, rather than using SetLastError. Godot will do both.
|
|
DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
|
|
|
|
if (s_pfnRasGetConnectStatusA == NULL)
|
|
s_pfnRasGetConnectStatusA = (pfnRGCS)GetRasProc("RasGetConnectStatusA");
|
|
|
|
if (s_pfnRasGetConnectStatusA)
|
|
{
|
|
RASCONNSTATUSA rcsa;
|
|
ZeroMemory(&rcsa, sizeof(RASCONNSTATUSA));
|
|
rcsa.dwSize = sizeof(RASCONNSTATUSA);
|
|
|
|
RetVal=(s_pfnRasGetConnectStatusA(hrasconn, &rcsa));
|
|
|
|
if(RetVal==0)
|
|
{
|
|
MultiByteToWideChar(g_acp, 0,
|
|
rcsa.szDeviceType, RAS_MaxDeviceType,
|
|
lprasconnstatus->szDeviceType, RAS_MaxDeviceType);
|
|
MultiByteToWideChar(g_acp, 0,
|
|
rcsa.szDeviceName, RAS_MaxDeviceName,
|
|
lprasconnstatus->szDeviceName, RAS_MaxDeviceName);
|
|
}
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=RasGetEntryDialParamsW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotRasGetEntryDialParamsW(LPCWSTR lpszPhonebook, LPRASDIALPARAMSW lprasdialparams, LPBOOL lpfPassword)
|
|
{
|
|
// if the call fails due to it not being on the OS (say like on
|
|
// win95), then it might return a "non-zero" error
|
|
// code, rather than using SetLastError. Godot will do both.
|
|
DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
|
|
|
|
if (s_pfnRasGetEntryDialParamsA == NULL)
|
|
s_pfnRasGetEntryDialParamsA = (pfnRGEDP)GetRasProc("RasGetEntryDialParamsA");
|
|
|
|
if (s_pfnRasGetEntryDialParamsA)
|
|
{
|
|
LPRASDIALPARAMSA lprdpa;
|
|
BOOL fOldStruct = (lprasdialparams->dwSize == CBRASDIALPARAMSOLDW);
|
|
|
|
if(fOldStruct)
|
|
{
|
|
_STACKALLOC(CBRASDIALPARAMSOLDA, lprdpa);
|
|
if(lprdpa==NULL)
|
|
return(ERROR_STACK_OVERFLOW);
|
|
ZeroMemory(lprdpa, CBRASDIALPARAMSOLDA);
|
|
lprdpa->dwSize = CBRASDIALPARAMSOLDA;
|
|
}
|
|
else
|
|
{
|
|
_STACKALLOC(CBRASDIALPARAMSNEWA, lprdpa);
|
|
if(lprdpa==NULL)
|
|
return(ERROR_STACK_OVERFLOW);
|
|
ZeroMemory(lprdpa, CBRASDIALPARAMSNEWA);
|
|
lprdpa->dwSize = CBRASDIALPARAMSNEWA;
|
|
}
|
|
|
|
RetVal=(s_pfnRasGetEntryDialParamsA(NULL, lprdpa, lpfPassword));
|
|
|
|
if(RetVal==0)
|
|
{
|
|
MultiByteToWideChar(g_acp, 0,
|
|
lprdpa->szEntryName, RAS_MaxEntryName,
|
|
lprasdialparams->szEntryName, RAS_MaxEntryName);
|
|
MultiByteToWideChar(g_acp, 0,
|
|
lprdpa->szPhoneNumber, RAS_MaxPhoneNumber,
|
|
lprasdialparams->szPhoneNumber, RAS_MaxPhoneNumber);
|
|
MultiByteToWideChar(g_acp, 0,
|
|
lprdpa->szCallbackNumber, RAS_MaxCallbackNumber,
|
|
lprasdialparams->szCallbackNumber, RAS_MaxCallbackNumber);
|
|
MultiByteToWideChar(g_acp, 0,
|
|
lprdpa->szUserName, UNLEN,
|
|
lprasdialparams->szUserName, UNLEN);
|
|
MultiByteToWideChar(g_acp, 0,
|
|
lprdpa->szPassword, PWLEN,
|
|
lprasdialparams->szPassword, PWLEN);
|
|
MultiByteToWideChar(g_acp, 0,
|
|
lprdpa->szDomain, DNLEN,
|
|
lprasdialparams->szDomain, DNLEN);
|
|
|
|
if(!fOldStruct)
|
|
{
|
|
lprasdialparams->dwSubEntry = lprdpa->dwSubEntry ;
|
|
lprasdialparams->dwCallbackId = lprdpa->dwCallbackId;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
UNREFERENCED_PARAMETER(lpszPhonebook);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=RasGetEntryPropertiesW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotRasGetEntryPropertiesW( LPCWSTR lpszPhonebook,
|
|
LPCWSTR lpszEntry,
|
|
LPRASENTRYW lpRasEntry,
|
|
DWORD * lpdwEntryInfoSize,
|
|
LPBYTE lpbDeviceInfo,
|
|
LPDWORD lpdwDeviceInfoSize
|
|
)
|
|
{
|
|
// We do not support dwAlternateOffset presently. Neither does QuintinB in
|
|
// the RAS Connection Manager. If this was needed then someone would have
|
|
// to do the work. For now its a known limitation of Godot.
|
|
|
|
// if the call fails due to it not being on the OS (say like on
|
|
// win95), then it might return a "non-zero" error
|
|
// code, rather than using SetLastError. Godot will do both.
|
|
DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
|
|
|
|
if (s_pfnRasGetEntryPropertiesA == NULL)
|
|
s_pfnRasGetEntryPropertiesA = (pfnRGEP)GetRasProc("RasGetEntryPropertiesA");
|
|
|
|
if (s_pfnRasGetEntryPropertiesA)
|
|
{
|
|
if(RAS_MaxEntryName < gwcslen(lpszEntry))
|
|
RetVal = ERROR_INVALID_PARAMETER;
|
|
else
|
|
{
|
|
char lpszEntryAnsi[RAS_MaxEntryName + 1];
|
|
LPRASENTRYA lprea;
|
|
DWORD dweisa;
|
|
BOOL f401Struct;
|
|
|
|
WideCharToMultiByte(g_acp, 0, lpszEntry, -1, lpszEntryAnsi, RAS_MaxEntryName, NULL, NULL);
|
|
|
|
if (lpRasEntry->dwSize > CBRASENTRYOLDW)
|
|
{
|
|
f401Struct = TRUE;
|
|
_STACKALLOC(CBRASENTRYOLDA, lprea);
|
|
if(lprea)
|
|
{
|
|
ZeroMemory(lprea, CBRASENTRYOLDA);
|
|
lprea->dwSize = CBRASENTRYOLDA;
|
|
dweisa = (DWORD)CBRASENTRYOLDA;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
f401Struct = FALSE;
|
|
_STACKALLOC(CBRASENTRYNEWA, lprea);
|
|
if(lprea)
|
|
{
|
|
ZeroMemory(lprea, CBRASENTRYNEWA);
|
|
lprea->dwSize = CBRASENTRYNEWA;
|
|
dweisa = (DWORD)CBRASENTRYNEWA;
|
|
}
|
|
}
|
|
|
|
if(lprea==NULL)
|
|
{
|
|
return(ERROR_STACK_OVERFLOW);
|
|
}
|
|
|
|
RetVal=(s_pfnRasGetEntryPropertiesA(NULL, lpszEntryAnsi, lprea, &dweisa,
|
|
lpbDeviceInfo, lpdwDeviceInfoSize));
|
|
|
|
if((RetVal==ERROR_SUCCESS) && lpRasEntry)
|
|
{
|
|
lpRasEntry->dwfOptions = lprea->dwfOptions;
|
|
|
|
// Location/phone number.
|
|
lpRasEntry->dwCountryID = lprea->dwCountryID;
|
|
lpRasEntry->dwCountryCode = lprea->dwCountryCode;
|
|
MultiByteToWideChar(g_acp, 0, lprea->szAreaCode, RAS_MaxAreaCode, lpRasEntry->szAreaCode, RAS_MaxAreaCode);
|
|
MultiByteToWideChar(g_acp, 0, lprea->szLocalPhoneNumber, RAS_MaxPhoneNumber, lpRasEntry->szLocalPhoneNumber, RAS_MaxPhoneNumber);
|
|
lpRasEntry->dwAlternateOffset = lprea->dwAlternateOffset;
|
|
|
|
// PPP/Ip
|
|
memcpy(&(lpRasEntry->ipaddr), &(lprea->ipaddr), sizeof(RASIPADDR));
|
|
memcpy(&(lpRasEntry->ipaddrDns), &(lprea->ipaddrDns), sizeof(RASIPADDR));
|
|
memcpy(&(lpRasEntry->ipaddrDnsAlt), &(lprea->ipaddrDnsAlt), sizeof(RASIPADDR));
|
|
memcpy(&(lpRasEntry->ipaddrWins), &(lprea->ipaddrWins), sizeof(RASIPADDR));
|
|
memcpy(&(lpRasEntry->ipaddrWinsAlt), &(lprea->ipaddrWinsAlt), sizeof(RASIPADDR));
|
|
|
|
// Framing
|
|
lpRasEntry->dwFrameSize = lprea->dwFrameSize;
|
|
lpRasEntry->dwfNetProtocols = lprea->dwfNetProtocols;
|
|
lpRasEntry->dwFramingProtocol = lprea->dwFramingProtocol;
|
|
|
|
// Scripting
|
|
MultiByteToWideChar(g_acp, 0, lprea->szScript, MAX_PATH, lpRasEntry->szScript, MAX_PATH);
|
|
|
|
// AutoDial
|
|
MultiByteToWideChar(g_acp, 0, lprea->szAutodialDll, MAX_PATH, lpRasEntry->szAutodialDll, MAX_PATH);
|
|
MultiByteToWideChar(g_acp, 0, lprea->szAutodialFunc, MAX_PATH, lpRasEntry->szAutodialFunc, MAX_PATH);
|
|
|
|
// Device
|
|
MultiByteToWideChar(g_acp, 0, lprea->szDeviceType, RAS_MaxDeviceType, lpRasEntry->szDeviceType, RAS_MaxDeviceType);
|
|
MultiByteToWideChar(g_acp, 0, lprea->szDeviceName, RAS_MaxDeviceName, lpRasEntry->szDeviceName, RAS_MaxDeviceName);
|
|
|
|
// X.25
|
|
MultiByteToWideChar(g_acp, 0, lprea->szX25PadType, RAS_MaxPadType, lpRasEntry->szX25PadType, RAS_MaxPadType);
|
|
MultiByteToWideChar(g_acp, 0, lprea->szX25Address, RAS_MaxX25Address, lpRasEntry->szX25Address, RAS_MaxX25Address);
|
|
MultiByteToWideChar(g_acp, 0, lprea->szX25Facilities, RAS_MaxFacilities, lpRasEntry->szX25Facilities, RAS_MaxFacilities);
|
|
MultiByteToWideChar(g_acp, 0, lprea->szX25UserData, RAS_MaxUserData, lpRasEntry->szX25UserData, RAS_MaxUserData);
|
|
lpRasEntry->dwChannels = lprea->dwChannels;
|
|
|
|
// Reserved - no need to copy but no reason not to
|
|
lpRasEntry->dwReserved1 = lprea->dwReserved1;
|
|
lpRasEntry->dwReserved2 = lprea->dwReserved2;
|
|
|
|
if(f401Struct)
|
|
{
|
|
lpRasEntry->dwSubEntries = lprea->dwSubEntries;
|
|
lpRasEntry->dwDialMode = lprea->dwDialMode;
|
|
lpRasEntry->dwDialExtraPercent = lprea->dwDialExtraPercent;
|
|
lpRasEntry->dwDialExtraSampleSeconds = lprea->dwDialExtraSampleSeconds;
|
|
lpRasEntry->dwHangUpExtraPercent = lprea->dwHangUpExtraPercent;
|
|
lpRasEntry->dwHangUpExtraSampleSeconds = lprea->dwHangUpExtraSampleSeconds;
|
|
lpRasEntry->dwIdleDisconnectSeconds = lprea->dwIdleDisconnectSeconds;
|
|
}
|
|
}
|
|
else if ((ERROR_BUFFER_TOO_SMALL == RetVal) || !lpRasEntry)
|
|
{
|
|
// We don't know the actual size since we are passing a RASENTRYA, but
|
|
// the user only knows about RASENTRYW. Thus double the returned size
|
|
// and we will call it a day.
|
|
*lpdwEntryInfoSize = dweisa*sizeof(WCHAR);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
UNREFERENCED_PARAMETER(lpszPhonebook);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=RasGetErrorStringW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotRasGetErrorStringW(UINT uErrorValue, LPWSTR lpszErrorString, DWORD cBufSize)
|
|
{
|
|
// if the call fails due to it not being on the OS (say like on
|
|
// win95), then it might return a "non-zero" error
|
|
// code, rather than using SetLastError. Godot will do both.
|
|
DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
|
|
|
|
if (s_pfnRasGetErrorStringA == NULL)
|
|
s_pfnRasGetErrorStringA = (pfnRGES)GetRasProc("RasGetErrorStringA");
|
|
|
|
if (s_pfnRasGetErrorStringA)
|
|
{
|
|
char lpszErrorStringAnsi[256 + 1];
|
|
|
|
RetVal=(s_pfnRasGetErrorStringA(uErrorValue, lpszErrorStringAnsi, cBufSize));
|
|
|
|
if (RetVal==ERROR_SUCCESS)
|
|
MultiByteToWideChar(g_acp, 0, lpszErrorStringAnsi, -1, lpszErrorString, cBufSize);
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=RasHangUpW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotRasHangUpW(HRASCONN hrasconn)
|
|
{
|
|
// if the call fails due to it not being on the OS (say like on
|
|
// win95), then it might return a "non-zero" error
|
|
// code, rather than using SetLastError. Godot will do both.
|
|
DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
|
|
|
|
if (s_pfnRasHangUpA == NULL)
|
|
s_pfnRasHangUpA = (pfnRHU)GetRasProc("RasHangUpA");
|
|
|
|
if (s_pfnRasHangUpA)
|
|
{
|
|
// Why the heck is this function A/W decorated, anyway?
|
|
// Its not like there are any strings here!
|
|
RetVal=(s_pfnRasHangUpA(hrasconn));
|
|
}
|
|
|
|
return(RetVal);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=RasRenameEntryW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotRasRenameEntryW(LPCWSTR lpszPhonebook, LPCWSTR lpszOldEntry, LPCWSTR lpszNewEntry)
|
|
{
|
|
// if the call fails due to it not being on the OS (say like on
|
|
// win95), then it might return a "non-zero" error
|
|
// code, rather than using SetLastError. Godot will do both.
|
|
DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
|
|
|
|
if (s_pfnRasRenameEntryA == NULL)
|
|
s_pfnRasRenameEntryA = (pfnRRE)GetRasProc("RasRenameEntryA");
|
|
|
|
if (s_pfnRasRenameEntryA)
|
|
{
|
|
if((RAS_MaxEntryName < gwcslen(lpszOldEntry)) ||
|
|
(RAS_MaxEntryName < gwcslen(lpszNewEntry)))
|
|
RetVal = ERROR_INVALID_PARAMETER;
|
|
else
|
|
{
|
|
char lpszOldEntryAnsi[RAS_MaxEntryName + 1];
|
|
char lpszNewEntryAnsi[RAS_MaxEntryName + 1];
|
|
|
|
WideCharToMultiByte(g_acp, 0, lpszOldEntry, -1, lpszOldEntryAnsi, RAS_MaxEntryName, NULL, NULL);
|
|
WideCharToMultiByte(g_acp, 0, lpszNewEntry, -1, lpszNewEntryAnsi, RAS_MaxEntryName, NULL, NULL);
|
|
|
|
RetVal=(s_pfnRasRenameEntryA(NULL, lpszOldEntryAnsi, lpszNewEntryAnsi));
|
|
}
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
UNREFERENCED_PARAMETER(lpszPhonebook);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=RasSetEntryDialParamsW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotRasSetEntryDialParamsW(LPCWSTR lpszPhonebook, LPRASDIALPARAMSW lprasdialparams, BOOL fRemovePassword)
|
|
{
|
|
// if the call fails due to it not being on the OS (say like on
|
|
// win95), then it might return a "non-zero" error
|
|
// code, rather than using SetLastError. Godot will do both.
|
|
DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
|
|
|
|
if (s_pfnRasSetEntryDialParamsA == NULL)
|
|
s_pfnRasSetEntryDialParamsA = (pfnRSEDP)GetRasProc("RasSetEntryDialParamsA");
|
|
|
|
if (s_pfnRasSetEntryDialParamsA)
|
|
{
|
|
LPRASDIALPARAMSA lprdpa;
|
|
|
|
if (lprasdialparams->dwSize == CBRASDIALPARAMSOLDW)
|
|
{
|
|
_STACKALLOC(CBRASDIALPARAMSOLDA, lprdpa);
|
|
if(lprdpa)
|
|
lprdpa->dwSize = CBRASDIALPARAMSOLDA;
|
|
}
|
|
else
|
|
{
|
|
_STACKALLOC(CBRASDIALPARAMSNEWA, lprdpa);
|
|
if(lprdpa)
|
|
{
|
|
lprdpa->dwSize = CBRASDIALPARAMSNEWA;
|
|
lprdpa->dwSubEntry = lprasdialparams->dwSubEntry;
|
|
lprdpa->dwCallbackId = lprasdialparams->dwCallbackId;
|
|
}
|
|
}
|
|
|
|
if(lprdpa)
|
|
{
|
|
WideCharToMultiByte(g_acp, 0, lprasdialparams->szEntryName, RAS_MaxEntryName, lprdpa->szEntryName, RAS_MaxEntryName, NULL, NULL);
|
|
WideCharToMultiByte(g_acp, 0, lprasdialparams->szPhoneNumber, RAS_MaxPhoneNumber, lprdpa->szPhoneNumber, RAS_MaxPhoneNumber, NULL, NULL);
|
|
WideCharToMultiByte(g_acp, 0, lprasdialparams->szCallbackNumber, RAS_MaxCallbackNumber, lprdpa->szCallbackNumber, RAS_MaxCallbackNumber, NULL, NULL);
|
|
WideCharToMultiByte(g_acp, 0, lprasdialparams->szUserName, UNLEN, lprdpa->szUserName, UNLEN, NULL, NULL);
|
|
WideCharToMultiByte(g_acp, 0, lprasdialparams->szPassword, PWLEN, lprdpa->szPassword, PWLEN, NULL, NULL);
|
|
WideCharToMultiByte(g_acp, 0, lprasdialparams->szDomain, DNLEN, lprdpa->szDomain, DNLEN, NULL, NULL);
|
|
|
|
RetVal = (s_pfnRasSetEntryDialParamsA(NULL, lprdpa, fRemovePassword));
|
|
}
|
|
else
|
|
RetVal = ERROR_STACK_OVERFLOW;
|
|
}
|
|
|
|
return(RetVal);
|
|
UNREFERENCED_PARAMETER(lpszPhonebook);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=RasSetEntryPropertiesW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotRasSetEntryPropertiesW( LPCWSTR lpszPhonebook,
|
|
LPCWSTR lpszEntry,
|
|
LPRASENTRYW lpRasEntry,
|
|
DWORD dwEntryInfoSize,
|
|
LPBYTE lpbDeviceInfo,
|
|
DWORD dwDeviceInfoSize
|
|
)
|
|
{
|
|
// We do not support dwAlternateOffset presently. Neither does QuintinB
|
|
// in the RAS Connection Manager. If this was needed then someone would
|
|
// have to do the work. For now its a limitation of Godot.
|
|
|
|
// if the call fails due to it not being on the OS (say like on
|
|
// win95), then it might return a "non-zero" error code
|
|
DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
|
|
|
|
if (s_pfnRasSetEntryPropertiesA == NULL)
|
|
s_pfnRasSetEntryPropertiesA = (pfnRSEP)GetRasProc("RasSetEntryPropertiesA");
|
|
|
|
if (s_pfnRasSetEntryPropertiesA)
|
|
{
|
|
if(RAS_MaxEntryName < gwcslen(lpszEntry))
|
|
RetVal = ERROR_INVALID_PARAMETER;
|
|
else
|
|
{
|
|
LPRASENTRYA lprea;
|
|
char lpszEntryAnsi[RAS_MaxEntryName];
|
|
|
|
_STACKALLOC(CBRASENTRYNEWA, lprea);
|
|
if(lprea==NULL)
|
|
{
|
|
return(ERROR_STACK_OVERFLOW);
|
|
}
|
|
|
|
WideCharToMultiByte(g_acp, 0, lpszEntry, -1, lpszEntryAnsi, RAS_MaxEntryName, NULL, NULL);
|
|
ZeroMemory(lprea, CBRASENTRYNEWA);
|
|
lprea->dwfOptions = lpRasEntry->dwfOptions;
|
|
lprea->dwCountryID = lpRasEntry->dwCountryID;
|
|
lprea->dwCountryCode = lpRasEntry->dwCountryCode;
|
|
WideCharToMultiByte(g_acp, 0, lpRasEntry->szAreaCode, RAS_MaxAreaCode, lprea->szAreaCode, RAS_MaxAreaCode, NULL, NULL);
|
|
WideCharToMultiByte(g_acp, 0, lpRasEntry->szLocalPhoneNumber, RAS_MaxPhoneNumber, lprea->szLocalPhoneNumber, RAS_MaxPhoneNumber, NULL, NULL);
|
|
lprea->dwAlternateOffset = lpRasEntry->dwAlternateOffset;
|
|
memcpy(&(lprea->ipaddr), &(lpRasEntry->ipaddr), sizeof(RASIPADDR));
|
|
memcpy(&(lprea->ipaddrDns), &(lpRasEntry->ipaddrDns), sizeof(RASIPADDR));
|
|
memcpy(&(lprea->ipaddrDnsAlt), &(lpRasEntry->ipaddrDnsAlt), sizeof(RASIPADDR));
|
|
memcpy(&(lprea->ipaddrWins), &(lpRasEntry->ipaddrWins), sizeof(RASIPADDR));
|
|
memcpy(&(lprea->ipaddrWinsAlt), &(lpRasEntry->ipaddrWinsAlt), sizeof(RASIPADDR));
|
|
lprea->dwFrameSize = lpRasEntry->dwFrameSize;
|
|
lprea->dwfNetProtocols = lpRasEntry->dwfNetProtocols;
|
|
lprea->dwFramingProtocol = lpRasEntry->dwFramingProtocol;
|
|
WideCharToMultiByte(g_acp, 0, lpRasEntry->szScript, MAX_PATH, lprea->szScript, MAX_PATH, NULL, NULL);
|
|
WideCharToMultiByte(g_acp, 0, lpRasEntry->szAutodialDll, MAX_PATH, lprea->szAutodialDll, MAX_PATH, NULL, NULL);
|
|
WideCharToMultiByte(g_acp, 0, lpRasEntry->szAutodialFunc, MAX_PATH, lprea->szAutodialFunc, MAX_PATH, NULL, NULL);
|
|
WideCharToMultiByte(g_acp, 0, lpRasEntry->szDeviceType, RAS_MaxDeviceType, lprea->szDeviceType, RAS_MaxDeviceType, NULL, NULL);
|
|
WideCharToMultiByte(g_acp, 0, lpRasEntry->szDeviceName, RAS_MaxDeviceName, lprea->szDeviceName, RAS_MaxDeviceName, NULL, NULL);
|
|
WideCharToMultiByte(g_acp, 0, lpRasEntry->szX25PadType, RAS_MaxPadType, lprea->szX25PadType, RAS_MaxPadType, NULL, NULL);
|
|
WideCharToMultiByte(g_acp, 0, lpRasEntry->szX25Address, RAS_MaxX25Address, lprea->szX25Address, RAS_MaxX25Address, NULL, NULL);
|
|
WideCharToMultiByte(g_acp, 0, lpRasEntry->szX25Facilities, RAS_MaxFacilities, lprea->szX25Facilities, RAS_MaxFacilities, NULL, NULL);
|
|
WideCharToMultiByte(g_acp, 0, lpRasEntry->szX25UserData, RAS_MaxUserData, lprea->szX25UserData, RAS_MaxUserData, NULL, NULL);
|
|
lprea->dwChannels = lpRasEntry->dwChannels;
|
|
lprea->dwReserved1 = lpRasEntry->dwReserved1;
|
|
lprea->dwReserved2 = lpRasEntry->dwReserved2;
|
|
if (lpRasEntry->dwSize > CBRASENTRYOLDW)
|
|
lprea->dwSize = CBRASENTRYOLDA;
|
|
else
|
|
{
|
|
lprea->dwSize = CBRASENTRYNEWA;
|
|
lprea->dwSubEntries = lpRasEntry->dwSubEntries;
|
|
lprea->dwDialMode = lpRasEntry->dwDialMode;
|
|
lprea->dwDialExtraPercent = lpRasEntry->dwDialExtraPercent;
|
|
lprea->dwDialExtraSampleSeconds = lpRasEntry->dwDialExtraSampleSeconds;
|
|
lprea->dwHangUpExtraPercent = lpRasEntry->dwHangUpExtraPercent;
|
|
lprea->dwHangUpExtraSampleSeconds = lpRasEntry->dwHangUpExtraSampleSeconds;
|
|
lprea->dwIdleDisconnectSeconds = lpRasEntry->dwIdleDisconnectSeconds;
|
|
}
|
|
|
|
RetVal=(s_pfnRasSetEntryPropertiesA(NULL, lpszEntryAnsi, lprea, dwEntryInfoSize,
|
|
lpbDeviceInfo, dwDeviceInfoSize));
|
|
}
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
UNREFERENCED_PARAMETER(lpszPhonebook);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=RasSetSubEntryPropertiesW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotRasSetSubEntryPropertiesW(LPCWSTR lpszPhonebook, LPCWSTR lpszEntry, DWORD dwSubEntry,
|
|
struct tagRASSUBENTRYW * lpRasSubEntry, DWORD dwcbRasSubEntry,
|
|
LPBYTE lpbDeviceConfig, DWORD dwcbDeviceConfig)
|
|
{
|
|
// if the call fails due to it not being on the OS (say like on
|
|
// win95/win98), then it might return a "non-zero" error code.
|
|
DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
|
|
|
|
if (s_pfnRasSetSubEntryPropertiesA == NULL)
|
|
s_pfnRasSetSubEntryPropertiesA = (pfnRSSEP)GetRasProc("RasSetSubEntryPropertiesA");
|
|
|
|
if (s_pfnRasSetSubEntryPropertiesA)
|
|
{
|
|
CHAR lpszEntryAnsi[RAS_MaxEntryName + 1];
|
|
int cch = WideCharToMultiByte(g_acp, 0, lpszEntry, -1, lpszEntryAnsi, RAS_MaxEntryName, NULL, NULL);
|
|
|
|
if(cch && (RAS_MaxEntryName >= cch))
|
|
{
|
|
LPRASSUBENTRYA lpRasSubEntryA;
|
|
DWORD dwcbRasSubEntryA;
|
|
size_t cchSub;
|
|
|
|
if(lpRasSubEntry->dwAlternateOffset)
|
|
cchSub = cchUnicodeMultiSz((LPWSTR)lpRasSubEntry + lpRasSubEntry->dwAlternateOffset);
|
|
else
|
|
cchSub = 0;
|
|
|
|
dwcbRasSubEntryA = sizeof(RASENTRYA) + (cchSub * g_mcs);
|
|
_STACKALLOC(dwcbRasSubEntryA, lpRasSubEntryA);
|
|
if(lpRasSubEntryA==NULL)
|
|
return(ERROR_STACK_OVERFLOW);
|
|
ZeroMemory(lpRasSubEntryA, dwcbRasSubEntryA);
|
|
lpRasSubEntryA->dwSize = sizeof(RASSUBENTRYA);
|
|
lpRasSubEntryA->dwfFlags = lpRasSubEntry->dwfFlags;
|
|
|
|
//
|
|
// Device
|
|
//
|
|
WideCharToMultiByte(g_acp,
|
|
0,
|
|
lpRasSubEntry->szDeviceType,
|
|
RAS_MaxDeviceType,
|
|
lpRasSubEntryA->szDeviceType,
|
|
RAS_MaxDeviceType,
|
|
NULL,
|
|
NULL);
|
|
WideCharToMultiByte(g_acp,
|
|
0,
|
|
lpRasSubEntry->szDeviceName,
|
|
RAS_MaxDeviceName,
|
|
lpRasSubEntryA->szDeviceName,
|
|
RAS_MaxDeviceName,
|
|
NULL,
|
|
NULL);
|
|
|
|
//
|
|
// Location/phone number.
|
|
//
|
|
WideCharToMultiByte(g_acp,
|
|
0,
|
|
lpRasSubEntry->szLocalPhoneNumber,
|
|
RAS_MaxPhoneNumber,
|
|
lpRasSubEntryA->szLocalPhoneNumber,
|
|
RAS_MaxPhoneNumber,
|
|
NULL,
|
|
NULL);
|
|
|
|
WideCharToMultiByte(g_acp,
|
|
0,
|
|
(LPWSTR)lpRasSubEntry + lpRasSubEntry->dwAlternateOffset,
|
|
cchSub,
|
|
(LPSTR)lpRasSubEntry + lpRasSubEntry->dwAlternateOffset,
|
|
cchSub * g_mcs,
|
|
NULL,
|
|
NULL);
|
|
|
|
RetVal=(s_pfnRasSetSubEntryPropertiesA(NULL, lpszEntryAnsi, dwSubEntry, lpRasSubEntryA,
|
|
dwcbRasSubEntryA, lpbDeviceConfig, dwcbDeviceConfig));
|
|
}
|
|
else
|
|
RetVal = ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
UNREFERENCED_PARAMETER(lpszPhonebook);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=RasValidateEntryNameW
|
|
Begin=
|
|
DWORD __stdcall GodotRasValidateEntryNameW(LPCWSTR lpszPhonebook, LPCWSTR lpszEntry)
|
|
{
|
|
// if the call fails due to it not being on the OS (say like on
|
|
// win95), then it might return a "non-zero" error code.
|
|
DWORD RetVal = ERROR_CALL_NOT_IMPLEMENTED;
|
|
|
|
if (s_pfnRasValidateEntryNameA == NULL)
|
|
s_pfnRasValidateEntryNameA = (pfnRVEN)GetRasProc("RasValidateEntryNameA");
|
|
|
|
if (s_pfnRasValidateEntryNameA)
|
|
{
|
|
if(RAS_MaxEntryName < gwcslen(lpszEntry))
|
|
RetVal = ERROR_INVALID_PARAMETER;
|
|
else
|
|
{
|
|
char lpszEntryAnsi[RAS_MaxEntryName];
|
|
|
|
WideCharToMultiByte(g_acp, 0, lpszEntry, -1, lpszEntryAnsi, RAS_MaxEntryName, NULL, NULL);
|
|
|
|
RetVal=(s_pfnRasValidateEntryNameA(NULL, lpszEntryAnsi));
|
|
}
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
UNREFERENCED_PARAMETER(lpszPhonebook);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=RealGetWindowClassW
|
|
Begin=
|
|
UINT __stdcall
|
|
GodotRealGetWindowClassW(HWND hwnd, LPWSTR pszType, UINT cchType)
|
|
{
|
|
// Begin locals
|
|
UINT RetVal;
|
|
LPSTR pszTypeAnsi;
|
|
|
|
_STACKALLOC((cchType*g_mcs)+1, pszTypeAnsi);
|
|
|
|
// Call the 'A' version of the API
|
|
RetVal=RealGetWindowClassA(hwnd, pszTypeAnsi, cchType);
|
|
|
|
// Begin postcall
|
|
if(RetVal)
|
|
{
|
|
MultiByteToWideChar(g_acp, 0, pszTypeAnsi, -1, pszType, cchType);
|
|
}
|
|
else if(pszType)
|
|
{
|
|
*pszType = 0;
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=ReadConsoleOutputCharacterW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotReadConsoleOutputCharacterW( HANDLE hConsoleOutput,
|
|
LPWSTR lpCharacter,
|
|
DWORD nLength,
|
|
COORD dwReadCoord,
|
|
LPDWORD lpcchRead
|
|
)
|
|
{
|
|
// Begin locals
|
|
BOOL RetVal;
|
|
LPSTR lpCharacterAnsi;
|
|
|
|
_STACKALLOC((nLength*g_mcs)+1, lpCharacterAnsi);
|
|
if(lpCharacterAnsi==NULL && lpCharacter != NULL)
|
|
{
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(FALSE);
|
|
}
|
|
|
|
// Call the 'A' version of the API
|
|
RetVal=ReadConsoleOutputCharacterA(hConsoleOutput, lpCharacterAnsi, nLength, dwReadCoord, lpcchRead);
|
|
|
|
// Begin postcall
|
|
if(RetVal && lpCharacter && lpCharacterAnsi)
|
|
MultiByteToWideChar(g_oemcp, 0, lpCharacterAnsi, -1, lpCharacter, *(lpcchRead));
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=RegEnumKeyW
|
|
Begin=
|
|
LONG __stdcall
|
|
GodotRegEnumKeyW(HKEY hKey, DWORD dwIndex, LPWSTR lpName, DWORD cbName)
|
|
{
|
|
// Begin locals
|
|
LONG RetVal;
|
|
LPSTR lpNameAnsi;
|
|
|
|
// Copied from the OS API's param validation
|
|
if (IsBadWritePtr(lpName, cbName))
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
// Alloc a string of like size.
|
|
_STACKALLOC((cbName*g_mcs)+1, lpNameAnsi);
|
|
if(lpNameAnsi==NULL)
|
|
{
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(0);
|
|
}
|
|
|
|
// Call the 'A' version of the API
|
|
RetVal=RegEnumKeyA(hKey, dwIndex, lpNameAnsi, cbName);
|
|
|
|
// Begin postcall
|
|
if(RetVal == ERROR_SUCCESS)
|
|
MultiByteToWideChar(g_acp, 0, lpNameAnsi, -1, lpName, cbName);
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=RegEnumKeyExW
|
|
Begin=
|
|
LONG __stdcall
|
|
GodotRegEnumKeyExW( HKEY hKey,
|
|
DWORD dwIndex,
|
|
LPWSTR lpName,
|
|
LPDWORD lpcbName,
|
|
LPDWORD lpReserved,
|
|
LPWSTR lpClass,
|
|
LPDWORD lpcbClass,
|
|
PFILETIME lpftLWT
|
|
)
|
|
{
|
|
// Begin locals
|
|
LONG RetVal;
|
|
LPSTR lpNameAnsi, lpClassAnsi;
|
|
DWORD cbName, cbClass;
|
|
|
|
if (lpcbName)
|
|
{
|
|
cbName = sizeof(WCHAR) * *lpcbName;
|
|
_STACKALLOC(cbName, lpNameAnsi);
|
|
}
|
|
else
|
|
{
|
|
cbName = 0;
|
|
lpNameAnsi = NULL;
|
|
}
|
|
|
|
if (lpcbClass)
|
|
{
|
|
cbClass = sizeof(WCHAR) * (*lpcbClass);
|
|
_STACKALLOC(cbClass, lpClassAnsi);
|
|
}
|
|
else
|
|
{
|
|
cbClass = 0;
|
|
lpClassAnsi = NULL;
|
|
}
|
|
|
|
// Call the 'A' version of the API
|
|
RetVal=RegEnumKeyExA(hKey, dwIndex, lpNameAnsi, &cbName, lpReserved, lpClassAnsi, &cbClass, lpftLWT);
|
|
|
|
// Begin postcall
|
|
if(RetVal == ERROR_SUCCESS)
|
|
{
|
|
DWORD cch;
|
|
if(lpName && lpcbName)
|
|
{
|
|
cch = MultiByteToWideChar(g_acp, 0, lpNameAnsi, cbName, lpName, *lpcbName);
|
|
if(cbName && !cch)
|
|
RetVal = ERROR_BUFFER_OVERFLOW;
|
|
*lpcbName = cch;
|
|
}
|
|
else if (lpcbName)
|
|
{
|
|
*lpcbName = 0;
|
|
}
|
|
|
|
if(lpClass && lpcbClass)
|
|
{
|
|
cch = MultiByteToWideChar(g_acp, 0, lpClassAnsi, cbClass, lpClass, *lpcbClass);
|
|
if(cbName && !cch)
|
|
RetVal = ERROR_BUFFER_OVERFLOW;
|
|
*lpcbClass = cch;
|
|
}
|
|
else if (lpcbClass)
|
|
{
|
|
*lpcbClass = 0;
|
|
}
|
|
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=RegEnumValueW
|
|
Begin=
|
|
LONG __stdcall GodotRegEnumValueW( HKEY hKey,
|
|
DWORD dwIndex,
|
|
LPWSTR lpValueName,
|
|
LPDWORD lpcbValueName, // this is cch, not cb, in the W case!!!
|
|
LPDWORD lpReserved,
|
|
LPDWORD lpType, // may be NULL
|
|
LPBYTE lpData, // may be NULL
|
|
LPDWORD lpcbData) // may be NULL -- but only if lpData is NULL
|
|
{
|
|
// Begin locals
|
|
LONG RetVal;
|
|
LPSTR szValue;
|
|
DWORD dwType;
|
|
DWORD cbValueName;
|
|
DWORD cbData;
|
|
|
|
// Required pointers:
|
|
if (!lpValueName || !lpcbValueName || (!lpcbData && lpData))
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
cbValueName = *lpcbValueName;
|
|
_STACKALLOC((cbValueName)*g_mcs, szValue);
|
|
if(szValue==NULL)
|
|
{
|
|
return(ERROR_STACK_OVERFLOW);
|
|
}
|
|
if(lpcbData)
|
|
cbData = *lpcbData;
|
|
else
|
|
cbData = 0;
|
|
|
|
// First call for informational purposes: type, etc. We
|
|
// do get the name, here (since we always get the name).
|
|
RetVal = RegEnumValueA(hKey, dwIndex, szValue, &cbValueName, lpReserved, &dwType, NULL, &cbData);
|
|
|
|
// Always copy the type info if the caller asked for it
|
|
if(lpType)
|
|
*lpType = dwType;
|
|
|
|
if(RetVal != ERROR_SUCCESS)
|
|
{
|
|
if(lpcbData)
|
|
*lpcbData = cbData;
|
|
|
|
if(lpcbValueName)
|
|
*lpcbValueName = cbValueName;
|
|
}
|
|
else
|
|
{
|
|
// We should always make it here unless they did something *really* awful
|
|
*lpcbValueName = MultiByteToWideChar(g_acp, 0, szValue, cbValueName, lpValueName, *lpcbValueName);
|
|
if(*lpcbValueName == 0)
|
|
{
|
|
// They did not give us enough of a buffer: this can happen on
|
|
// DBCS platforms with single-byte data (the *g_mcs buffer we
|
|
// allocated was big enough, but theirs is not).
|
|
RetVal = ERROR_INSUFFICIENT_BUFFER;
|
|
lpValueName[0] = L'\0';
|
|
|
|
// Note that the buffer we will ask for (below)
|
|
// can be bigger than necessary for the DBCS case.
|
|
*lpcbValueName = cbValueName * sizeof(WCHAR);
|
|
}
|
|
else if(lpData && lpcbData)
|
|
{
|
|
switch(dwType)
|
|
{
|
|
case REG_SZ:
|
|
case REG_EXPAND_SZ:
|
|
case REG_MULTI_SZ:
|
|
{
|
|
// we got the size already, so lets use it
|
|
LPSTR lpDataAnsi = GodotHeapAlloc(cbData);
|
|
|
|
if(lpDataAnsi==NULL)
|
|
{
|
|
return(ERROR_OUTOFMEMORY);
|
|
}
|
|
|
|
RetVal = RegEnumValueA(hKey, dwIndex, szValue, &cbValueName,
|
|
lpReserved, &dwType, (LPBYTE)lpDataAnsi, &cbData);
|
|
if(dwType==REG_MULTI_SZ)
|
|
{
|
|
DWORD cchData = GrszToGrwz(lpDataAnsi, (LPWSTR)lpData, *lpcbData/sizeof(WCHAR));
|
|
|
|
// If they did not give us enough buffer, tell them!
|
|
if ((*lpcbData > 0) && (cchData > *lpcbData/sizeof(WCHAR)))
|
|
RetVal = ERROR_MORE_DATA;
|
|
|
|
*lpcbData = cchData * sizeof(WCHAR);
|
|
}
|
|
else
|
|
{
|
|
LPWSTR lpDataT;
|
|
|
|
_STACKALLOC(cbData * sizeof(WCHAR), lpDataT);
|
|
|
|
MultiByteToWideChar(g_acp, 0, lpDataAnsi, cbData, lpDataT, cbData);
|
|
cbData = gwcslen(lpDataT) * sizeof(WCHAR);
|
|
|
|
if (cbData > *lpcbData)
|
|
{
|
|
// If they did not give us enough buffer, tell them!
|
|
if(*lpcbData > 0)
|
|
RetVal = ERROR_MORE_DATA;
|
|
}
|
|
else
|
|
{
|
|
RetVal = ERROR_SUCCESS;
|
|
memcpy(lpData, lpDataT, cbData);
|
|
}
|
|
*lpcbData = cbData;
|
|
}
|
|
GodotHeapFree(lpDataAnsi);
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
// some non-string type of data: the name has
|
|
// been done, let the API do all of the rest now.
|
|
RetVal = RegEnumValueA(hKey, dwIndex, szValue, &cbValueName,
|
|
lpReserved, lpType, lpData, lpcbData);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=RegisterDeviceNotificationW
|
|
Begin=
|
|
HDEVNOTIFY __stdcall
|
|
GodotRegisterDeviceNotificationW(HANDLE hRecipient, LPVOID NotificationFilter, DWORD Flags)
|
|
{
|
|
// Begin locals
|
|
HDEVNOTIFY RetVal = NULL;
|
|
|
|
__try
|
|
{
|
|
if (s_pfnRegisterDeviceNotificationA == NULL)
|
|
{
|
|
// Must allocate stuff for this API call
|
|
s_pfnRegisterDeviceNotificationA = (PFNrdna)GetUserProc("RegisterDeviceNotificationA");
|
|
}
|
|
|
|
if (s_pfnRegisterDeviceNotificationA)
|
|
{
|
|
size_t NameLength;
|
|
PDEV_BROADCAST_HDR dbh = NotificationFilter;
|
|
|
|
if (dbh->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
|
|
{
|
|
PDEV_BROADCAST_DEVICEINTERFACE_A dbdia;
|
|
PDEV_BROADCAST_DEVICEINTERFACE_W dbdiw = NotificationFilter;
|
|
|
|
_STACKALLOC(sizeof(DEV_BROADCAST_DEVICEINTERFACE_A), dbdia);
|
|
if(dbdia==NULL)
|
|
{
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(0);
|
|
}
|
|
ZeroMemory(dbdia, sizeof(DEV_BROADCAST_DEVICEINTERFACE_A));
|
|
dbdia->dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE_A);
|
|
dbdia->dbcc_devicetype = dbdiw->dbcc_devicetype;
|
|
dbdia->dbcc_reserved = dbdiw->dbcc_reserved;
|
|
dbdia->dbcc_classguid = dbdiw->dbcc_classguid;
|
|
NameLength = gwcslen(dbdiw->dbcc_name);
|
|
*(char **)(dbdia->dbcc_name) = _alloca(NameLength);
|
|
WideCharToMultiByte(g_acp, 0,
|
|
dbdiw->dbcc_name, NameLength,
|
|
dbdia->dbcc_name, NameLength,
|
|
NULL, NULL);
|
|
RetVal = (s_pfnRegisterDeviceNotificationA (hRecipient, dbdia, Flags));
|
|
}
|
|
else if(dbh->dbch_devicetype == DBT_DEVTYP_PORT)
|
|
{
|
|
PDEV_BROADCAST_PORT_A dbpa;
|
|
PDEV_BROADCAST_PORT_W dbpw = NotificationFilter;
|
|
|
|
_STACKALLOC(sizeof(DEV_BROADCAST_PORT_A), dbpa);
|
|
if(dbpa==NULL)
|
|
{
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(0);
|
|
}
|
|
ZeroMemory(dbpa, sizeof(DEV_BROADCAST_PORT_A));
|
|
dbpa->dbcp_size = sizeof(DEV_BROADCAST_PORT_A);
|
|
dbpa->dbcp_devicetype = dbpw->dbcp_devicetype;
|
|
dbpa->dbcp_reserved = dbpw->dbcp_reserved;
|
|
NameLength = gwcslen(dbpw->dbcp_name);
|
|
*(char **)(dbpa->dbcp_name) = _alloca(NameLength);
|
|
WideCharToMultiByte(g_acp, 0,
|
|
dbpw->dbcp_name, NameLength,
|
|
dbpa->dbcp_name, NameLength,
|
|
NULL, NULL);
|
|
RetVal = (s_pfnRegisterDeviceNotificationA (hRecipient, dbpa, Flags));
|
|
}
|
|
else
|
|
{
|
|
// No changes needed! There are no strings in the other structures.
|
|
RetVal = (s_pfnRegisterDeviceNotificationA (hRecipient, NotificationFilter, Flags));
|
|
}
|
|
}
|
|
else
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
}
|
|
__except( EXCEPTION_EXECUTE_HANDLER )
|
|
{
|
|
gresetstkoflw();
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
RetVal = 0;
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=RegQueryInfoKeyW
|
|
Begin=
|
|
LONG __stdcall
|
|
GodotRegQueryInfoKeyW( HKEY hKey,
|
|
LPWSTR lpClass,
|
|
LPDWORD lpcbClass,
|
|
LPDWORD lpReserved,
|
|
LPDWORD lpcSubKeys,
|
|
LPDWORD lpcbMaxSubKeyLen,
|
|
LPDWORD lpcbMaxClassLen,
|
|
LPDWORD lpcValues,
|
|
LPDWORD lpcbMaxValueNameLen,
|
|
LPDWORD lpcbMaxValueLen,
|
|
LPDWORD lpcbSecurityDescriptor,
|
|
PFILETIME lpftLastWriteTime
|
|
)
|
|
{
|
|
|
|
// Call the 'A' version of the API: Since there are no defined classess, we will
|
|
// conveniently ignore the param, thus giving us nothing to convert!
|
|
// We will pass the class and cbClass as is so that the API can validate for us.
|
|
return(RegQueryInfoKeyA(hKey,
|
|
(LPSTR)lpClass,
|
|
lpcbClass,
|
|
lpReserved,
|
|
lpcSubKeys,
|
|
lpcbMaxSubKeyLen,
|
|
lpcbMaxClassLen,
|
|
lpcValues,
|
|
lpcbMaxValueNameLen,
|
|
lpcbMaxValueLen,
|
|
lpcbSecurityDescriptor,
|
|
lpftLastWriteTime
|
|
));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=RegQueryMultipleValuesW
|
|
Begin=
|
|
// Max size for reg keys and values on Win9x
|
|
#define MAXREGKEYVALUESIZE 256
|
|
|
|
LONG __stdcall
|
|
GodotRegQueryMultipleValuesW( HKEY hKey,
|
|
PVALENTW val_list,
|
|
DWORD num_vals,
|
|
LPWSTR lpValueBuf,
|
|
LPDWORD ldwTotsize
|
|
)
|
|
{
|
|
LPSTR lpValueBufA = NULL;
|
|
PVALENTA val_listA = NULL;
|
|
LPSTR rgszNames = NULL;
|
|
LPSTR szName;
|
|
DWORD cchValue;
|
|
DWORD cbName;
|
|
LPDWORD pdwTotsize;
|
|
DWORD dwTotsize;
|
|
DWORD dwOffset;
|
|
UINT i;
|
|
LONG RetVal;
|
|
|
|
// Begin precall: we alloc on the heap here because NT does and
|
|
// because people can ask for a whole lot of memory!
|
|
|
|
// Alloc the space for the registry value information
|
|
val_listA = GodotHeapAlloc(sizeof(VALENTA) * num_vals);
|
|
if(val_listA == NULL)
|
|
{
|
|
RetVal = ERROR_OUTOFMEMORY;
|
|
goto Cleanup;
|
|
}
|
|
|
|
// Alloc the space for the registry names
|
|
rgszNames = GodotHeapAlloc(MAXREGKEYVALUESIZE * num_vals);
|
|
if(rgszNames == NULL)
|
|
{
|
|
RetVal = ERROR_OUTOFMEMORY;
|
|
goto Cleanup;
|
|
}
|
|
|
|
// Copy over their VALENTW info into our VALENTA, grabbing memory
|
|
// for the value names as needed.
|
|
szName = rgszNames;
|
|
dwOffset = 0;
|
|
for (i=0; i<num_vals; i++)
|
|
{
|
|
if (FSTRING_VALID(val_list[i].ve_valuename))
|
|
{
|
|
cbName = WideCharToMultiByte(g_acp,
|
|
0,
|
|
val_list[i].ve_valuename,
|
|
gwcslen(val_list[i].ve_valuename),
|
|
szName,
|
|
MAXREGKEYVALUESIZE,
|
|
NULL,
|
|
NULL);
|
|
val_listA[i].ve_valuename = szName;
|
|
szName += cbName;
|
|
dwOffset += cbName;
|
|
}
|
|
else
|
|
{
|
|
// Consider: isn't this impossible? C'mon now, it must be, right?
|
|
}
|
|
}
|
|
// CONSIDER: Do we want to realloc rgszNames now? At the moment it is
|
|
// (MAXREGKEYVALUESIZE * num_vals) and it only needs to be dwOffset.
|
|
// Not sure if the perf hit of the realloc to shrink is worth the
|
|
// gaining back of that extra heap space.
|
|
|
|
// Now allocate our buffer for everything. We know we have Unicode strings
|
|
// worth of space here, but perhaps there are no string values so we
|
|
// have to have an equally sized buffer
|
|
if(!ldwTotsize || (*ldwTotsize==0))
|
|
{
|
|
dwTotsize = 0;
|
|
lpValueBufA = NULL;
|
|
}
|
|
else
|
|
{
|
|
dwTotsize = *ldwTotsize;
|
|
lpValueBufA = GodotHeapAlloc(dwTotsize);
|
|
if(rgszNames == NULL)
|
|
{
|
|
RetVal = ERROR_OUTOFMEMORY;
|
|
goto Cleanup;
|
|
}
|
|
}
|
|
pdwTotsize = &dwTotsize;
|
|
|
|
// We made it this far, so call the API
|
|
RetVal=RegQueryMultipleValuesA(hKey, val_listA, num_vals, lpValueBufA, pdwTotsize);
|
|
|
|
// Begin postcall
|
|
if(RetVal == ERROR_SUCCESS)
|
|
{
|
|
dwOffset = 0;
|
|
for (i=0; i<num_vals; i++)
|
|
{
|
|
// Copy it all to start, a fallback scheme that NT uses. Notice
|
|
// that the only one we might change again is ve_valuelen, in
|
|
// the string types.
|
|
val_list[i].ve_valuelen = val_listA[i].ve_valuelen;
|
|
val_list[i].ve_type = val_listA[i].ve_type;
|
|
val_list[i].ve_valueptr = (DWORD_PTR)(lpValueBufA + dwOffset);
|
|
|
|
if ((val_list[i].ve_type == REG_SZ) ||
|
|
(val_list[i].ve_type == REG_EXPAND_SZ) ||
|
|
(val_list[i].ve_type == REG_MULTI_SZ))
|
|
|
|
{
|
|
// String-type values
|
|
cchValue = MultiByteToWideChar(g_acp,
|
|
0,
|
|
(LPSTR)(lpValueBufA + val_listA[i].ve_valueptr),
|
|
val_listA[i].ve_valuelen,
|
|
(LPWSTR)lpValueBuf + dwOffset,
|
|
(*ldwTotsize - dwOffset));
|
|
// the length is whatever we copied. So update ve_valuelen
|
|
// and fix up the offset
|
|
val_list[i].ve_valuelen = cchValue;
|
|
dwOffset += cchValue;
|
|
}
|
|
else
|
|
{
|
|
// Non string-type values
|
|
CopyMemory((lpValueBuf + dwOffset),
|
|
(lpValueBufA + val_listA[i].ve_valueptr),
|
|
val_listA[i].ve_valuelen);
|
|
// fix up the offset
|
|
dwOffset += val_listA[i].ve_valuelen;
|
|
}
|
|
// Round dwOffset to DWORD boundaries? See BASE's regqmval.c for details
|
|
dwOffset = (dwOffset + sizeof(DWORD) - 1) & ~(sizeof(DWORD)-1);
|
|
|
|
}
|
|
|
|
}
|
|
else if(RetVal == ERROR_MORE_DATA)
|
|
{
|
|
// We need to thunk the Ansi required bytes back to Unicode. But
|
|
// there is not really any way to do this without having the data
|
|
// available. So just return the required bytes for the Ansi
|
|
// data (* 2 on non-DBCS), as this should always be enough.
|
|
if (ldwTotsize != NULL)
|
|
*ldwTotsize = (FDBCS_CPG(g_acp) ? *pdwTotsize : (*pdwTotsize * 2));
|
|
}
|
|
|
|
Cleanup:
|
|
if(rgszNames)
|
|
GodotHeapFree(rgszNames);
|
|
if(val_listA)
|
|
GodotHeapFree(val_listA);
|
|
if(lpValueBufA)
|
|
GodotHeapFree(lpValueBufA);
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=RegQueryValueW
|
|
Begin=
|
|
LONG __stdcall
|
|
GodotRegQueryValueW(HKEY hKey, LPCWSTR lpSubKey, LPWSTR lpValue, PLONG lpcbValue)
|
|
{
|
|
// Begin locals
|
|
LONG RetVal;
|
|
LPSTR lpSubKeyAnsi;
|
|
LPSTR lpValueAnsi;
|
|
|
|
// Begin precall
|
|
GODOT_TO_ACP_STACKALLOC(lpSubKey, lpSubKeyAnsi);
|
|
_STACKALLOC((*lpcbValue*g_mcs)+1, lpValueAnsi);
|
|
if(!lpValueAnsi ||
|
|
(!lpSubKeyAnsi && lpSubKey))
|
|
{
|
|
return(ERROR_STACK_OVERFLOW);
|
|
}
|
|
|
|
RetVal=RegQueryValueA(hKey, lpSubKeyAnsi, lpValueAnsi, lpcbValue);
|
|
|
|
if(RetVal == ERROR_SUCCESS)
|
|
{
|
|
if(0 < MultiByteToWideChar(g_acp, 0, lpValueAnsi, -1, lpValue, *lpcbValue))
|
|
{
|
|
*lpcbValue = gwcslen(lpValue);
|
|
}
|
|
else
|
|
{
|
|
// The conversion failed for some reason, we assume due to an invalid buffer?
|
|
RetVal = ERROR_INSUFFICIENT_BUFFER;
|
|
}
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=RegQueryValueExW
|
|
Begin=
|
|
LONG __stdcall
|
|
GodotRegQueryValueExW( HKEY hKey,
|
|
LPCWSTR lpValueName,
|
|
LPDWORD lpReserved,
|
|
LPDWORD lpType,
|
|
LPBYTE lpData,
|
|
LPDWORD lpcbData
|
|
)
|
|
{
|
|
// Begin locals
|
|
LONG RetVal;
|
|
LPSTR lpValueNameAnsi;
|
|
DWORD dwType = 0;
|
|
DWORD cbData = 0;
|
|
|
|
// Begin precall
|
|
GODOT_TO_ACP_STACKALLOC(lpValueName, lpValueNameAnsi);
|
|
if(!lpValueNameAnsi && lpValueName)
|
|
return(ERROR_STACK_OVERFLOW);
|
|
|
|
// Ok, first call to get the type and size info
|
|
RetVal = RegQueryValueExA(hKey, lpValueNameAnsi, lpReserved, &dwType, NULL, &cbData);
|
|
|
|
if(lpType)
|
|
*lpType = dwType;
|
|
|
|
// Only do more work if they specified a buffer space; Note that
|
|
// the call we just made can only fail if the hKey is invalid or
|
|
// the value does not exist.
|
|
if((RetVal == ERROR_SUCCESS) && lpcbData)
|
|
{
|
|
switch(dwType)
|
|
{
|
|
case REG_SZ:
|
|
case REG_EXPAND_SZ:
|
|
case REG_MULTI_SZ:
|
|
{
|
|
LPSTR lpDataA;
|
|
DWORD cbNeeded;
|
|
|
|
// Alloc the space we need; Note that the call that filled
|
|
// cbData includes the terminating null character.
|
|
_STACKALLOC(cbData, lpDataA);
|
|
RetVal = RegQueryValueExA(hKey,
|
|
lpValueNameAnsi,
|
|
lpReserved,
|
|
&dwType,
|
|
(LPBYTE)lpDataA,
|
|
&cbData);
|
|
|
|
// Calc how many bytes we might need for a Unicode string.
|
|
// Note this might be an over-estimation in the DBCS case.
|
|
// CONSIDER: Perhaps we should just try to convert rather than
|
|
// guessing this way?
|
|
cbNeeded = ((cbData + 1) * sizeof(WCHAR));
|
|
|
|
if(cbNeeded > *lpcbData)
|
|
{
|
|
// If they passed a NULL buffer size, then we simply
|
|
// tell them we succeeded, otherwise we have to tell
|
|
// them there is more data
|
|
if(*lpcbData != 0)
|
|
RetVal = ERROR_MORE_DATA;
|
|
}
|
|
else if(lpData)
|
|
{
|
|
MultiByteToWideChar(g_acp, 0, lpDataA, cbData*g_mcs, (LPWSTR)lpData, cbData);
|
|
}
|
|
|
|
*lpcbData = cbNeeded;
|
|
break;
|
|
}
|
|
default:
|
|
// some non-string type of data, see if there is enough room;
|
|
// if there is, go for it (copy the length either way)
|
|
if(*lpcbData < cbData)
|
|
RetVal = ERROR_MORE_DATA;
|
|
else if(lpData)
|
|
RetVal = RegQueryValueExA(hKey, lpValueNameAnsi, lpReserved, lpType, lpData, lpcbData);
|
|
|
|
*lpcbData = cbData;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=RegisterClassW
|
|
Begin=
|
|
ATOM __stdcall
|
|
GodotRegisterClassW(const WNDCLASSW * lpWndClass)
|
|
{
|
|
// Begin locals
|
|
WNDCLASSA wca;
|
|
|
|
// Begin precall
|
|
ZeroMemory(&wca, sizeof(WNDCLASSA));
|
|
memcpy(&wca, lpWndClass, sizeof(UINT)+sizeof(WNDPROC)+2*sizeof(int)+4*sizeof(HANDLE));
|
|
GODOT_TO_ACP_STACKALLOC(lpWndClass->lpszMenuName, wca.lpszMenuName);
|
|
GODOT_TO_ACP_STACKALLOC(lpWndClass->lpszClassName, wca.lpszClassName);
|
|
|
|
// Call the 'A' version of the API
|
|
return(RegisterClassA(&wca));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=RegisterClassExW
|
|
Begin=
|
|
ATOM __stdcall
|
|
GodotRegisterClassExW(const WNDCLASSEXW * lpwcx)
|
|
{
|
|
// Begin locals
|
|
WNDCLASSEXA wcxa;
|
|
|
|
// Begin precall
|
|
ZeroMemory(&wcxa, sizeof(WNDCLASSEXA));
|
|
memcpy(&wcxa, lpwcx, 2*sizeof(UINT)+sizeof(WNDPROC)+2*sizeof(int)+4*sizeof(HANDLE));
|
|
GODOT_TO_ACP_STACKALLOC(lpwcx->lpszMenuName, wcxa.lpszMenuName);
|
|
GODOT_TO_ACP_STACKALLOC(lpwcx->lpszClassName, wcxa.lpszClassName);
|
|
wcxa.hIconSm = lpwcx->hIconSm;
|
|
|
|
// Call the 'A' version of the API
|
|
return(RegisterClassExA(&wcxa));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=RegSetValueExW
|
|
Begin=
|
|
LONG __stdcall
|
|
GodotRegSetValueExW( HKEY hKey,
|
|
LPCWSTR lpValueName,
|
|
DWORD Reserved,
|
|
DWORD dwType,
|
|
const BYTE * lpData,
|
|
DWORD cbData
|
|
)
|
|
{
|
|
// Begin locals
|
|
LONG RetVal;
|
|
LPSTR lpValueNameAnsi;
|
|
BYTE * lpDataAnsi = NULL;
|
|
size_t cchData;
|
|
|
|
// Begin precall
|
|
GODOT_TO_ACP_STACKALLOC(lpValueName, lpValueNameAnsi);
|
|
if(!lpValueNameAnsi && lpValueName)
|
|
return(ERROR_STACK_OVERFLOW);
|
|
|
|
switch (dwType)
|
|
{
|
|
case REG_MULTI_SZ:
|
|
case REG_SZ:
|
|
case REG_EXPAND_SZ:
|
|
{
|
|
size_t cbDataAnsi;
|
|
|
|
if (FSTRING_VALID((LPWSTR)lpData))
|
|
{
|
|
// Lets go for the minimal buffer we can reasonably get away with
|
|
if(dwType == REG_MULTI_SZ)
|
|
cchData = cchUnicodeMultiSz((LPWSTR)lpData) +1;
|
|
else
|
|
cchData = gwcslen((LPWSTR)lpData) + 1;
|
|
|
|
// Convert the information to ANSI and call the API with it
|
|
_STACKALLOC((cchData * g_mcs) + 1, lpDataAnsi);
|
|
if(lpDataAnsi==NULL)
|
|
{
|
|
return(ERROR_STACK_OVERFLOW);
|
|
}
|
|
ZeroMemory(lpDataAnsi, (cchData * g_mcs) + 1);
|
|
WideCharToMultiByte(g_acp, 0,
|
|
(LPWSTR)lpData, cchData,
|
|
(LPSTR)lpDataAnsi, (cchData * g_mcs),
|
|
NULL, NULL);
|
|
|
|
if(dwType == REG_MULTI_SZ)
|
|
cbDataAnsi = cbAnsiMultiSz((LPSTR)lpDataAnsi);
|
|
else
|
|
cbDataAnsi = lstrlenA((LPSTR)lpDataAnsi);
|
|
|
|
RetVal=RegSetValueExA(hKey,
|
|
lpValueNameAnsi,
|
|
Reserved,
|
|
dwType,
|
|
lpDataAnsi,
|
|
cbDataAnsi);
|
|
}
|
|
else
|
|
RetVal = ERROR_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
// Unknown data, just call straight through.
|
|
RetVal=RegSetValueExA(hKey, lpValueNameAnsi, Reserved, dwType, lpData, cbData);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=RemoveDirectoryW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotRemoveDirectoryW(LPCWSTR lpPathName)
|
|
{
|
|
LPSTR lpPathNameAnsi;
|
|
|
|
// Begin precall
|
|
GODOT_TO_CPG_STACKALLOC(lpPathName, lpPathNameAnsi, FILES_CPG, g_mcs);
|
|
if(lpPathNameAnsi==NULL)
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
return(RemoveDirectoryA(lpPathNameAnsi));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=RemovePropA
|
|
Begin=
|
|
HANDLE __stdcall
|
|
GodotRemovePropA(HWND hWnd, LPCSTR lpString)
|
|
{
|
|
if(IsInternalWindowProperty((LPWSTR)lpString, FALSE))
|
|
return(0);
|
|
|
|
return(RemovePropA(hWnd, lpString));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=RemovePropW
|
|
Begin=
|
|
HANDLE __stdcall
|
|
GodotRemovePropW(HWND hWnd, LPCWSTR lpString)
|
|
{
|
|
LPSTR lpStringAnsi;
|
|
|
|
if(IsInternalWindowProperty(lpString, TRUE))
|
|
return(0);
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lpString, lpStringAnsi);
|
|
if(!lpStringAnsi && lpString)
|
|
return(0);
|
|
|
|
return(RemovePropA(hWnd, lpStringAnsi));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=ReplaceTextW
|
|
Begin=
|
|
HWND __stdcall
|
|
GodotReplaceTextW(LPFINDREPLACEW lpfr)
|
|
{
|
|
return(FindReplaceTextHelper(lpfr, FALSE));
|
|
}
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=ResetDCW
|
|
Begin=
|
|
HDC __stdcall
|
|
GodotResetDCW(HDC hdc, DEVMODEW * lpInitData)
|
|
{
|
|
LPDEVMODEA lpdma;
|
|
|
|
_STACKALLOC(sizeof(DEVMODEA) + (lpInitData ? lpInitData->dmDriverExtra : 0), lpdma);
|
|
if(lpdma==NULL)
|
|
{
|
|
return(0);
|
|
}
|
|
ZeroMemory(lpdma, sizeof(DEVMODEA) + (lpInitData ? lpInitData->dmDriverExtra : 0));
|
|
if(lpInitData)
|
|
DevModeAfromW(lpdma, lpInitData);
|
|
return(ResetDCA(hdc, lpdma));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=ResetPrinterW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotResetPrinterW(HANDLE hPrinter, LPPRINTER_DEFAULTSW pDefault)
|
|
{
|
|
PRINTER_DEFAULTSA pda;
|
|
LPDEVMODEW lpdmW;
|
|
BOOL RetVal = FALSE;
|
|
|
|
// Begin precall
|
|
ZeroMemory(&pda, sizeof(PRINTER_DEFAULTSA));
|
|
lpdmW = pDefault->pDevMode;
|
|
pda.pDevMode = GodotHeapAlloc(sizeof(DEVMODEA) + lpdmW->dmDriverExtra);
|
|
if(pda.pDevMode)
|
|
{
|
|
ZeroMemory(pda.pDevMode, sizeof(DEVMODEA) + lpdmW->dmDriverExtra);
|
|
DevModeAfromW(pda.pDevMode, lpdmW);
|
|
GODOT_TO_ACP_STACKALLOC(pDefault->pDatatype, pda.pDatatype);
|
|
|
|
RetVal = ResetPrinterA(hPrinter, &pda);
|
|
GodotHeapFree(pda.pDevMode);
|
|
}
|
|
else
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
|
|
return(RetVal);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=SearchPathW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotSearchPathW(LPCWSTR lpPath, LPCWSTR lpFileName, LPCWSTR lpExtension,
|
|
DWORD nBufferLength, LPWSTR lpBuffer, LPWSTR * lpFilePart)
|
|
{
|
|
// Begin locals
|
|
DWORD RetVal;
|
|
LPSTR lpPathAnsi;
|
|
LPSTR lpFileNameAnsi;
|
|
LPSTR lpExtensionAnsi;
|
|
LPSTR lpBufferAnsi;
|
|
UINT cpg = FILES_CPG;
|
|
|
|
// Begin precall
|
|
GODOT_TO_CPG_STACKALLOC(lpPath, lpPathAnsi, cpg, g_mcs);
|
|
GODOT_TO_CPG_STACKALLOC(lpFileName, lpFileNameAnsi, cpg, g_mcs);
|
|
GODOT_TO_CPG_STACKALLOC(lpExtension, lpExtensionAnsi, cpg, g_mcs);
|
|
_STACKALLOC((nBufferLength*g_mcs)+1, lpBufferAnsi);
|
|
|
|
RetVal=SearchPathA(lpPathAnsi,
|
|
lpFileNameAnsi,
|
|
lpExtensionAnsi,
|
|
nBufferLength*g_mcs,
|
|
lpBufferAnsi,
|
|
NULL);
|
|
|
|
if(RetVal)
|
|
{
|
|
MultiByteToWideChar(cpg, 0, lpBufferAnsi, nBufferLength*g_mcs, lpBuffer, nBufferLength);
|
|
|
|
if(lpFilePart)
|
|
{
|
|
WCHAR drive[_MAX_DRIVE];
|
|
WCHAR dir[_MAX_DIR];
|
|
|
|
// We do not bother with an ANSI version of lpFilePart and just derive it here
|
|
// (even non-technical folks like CWissink can contribute now and then!)
|
|
gwsplitpath(lpBuffer, drive, dir, NULL, NULL);
|
|
*lpFilePart = lpBuffer + gwcslen(drive) + gwcslen(dir);
|
|
}
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=SendDlgItemMessageW
|
|
Begin=
|
|
LRESULT __stdcall
|
|
GodotSendDlgItemMessageW(HWND hDlg, int nIDDlgItem, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
HWND hWnd = GetDlgItem(hDlg, nIDDlgItem);
|
|
|
|
// if the GetDlgItem fails, we will leave SetLastError alone (it
|
|
// will probably be ERROR_CONTROL_ID_NOT_FOUND anyway).
|
|
if (hWnd)
|
|
{
|
|
// Rather than going through SendDlgItemMessageA, we just
|
|
// do what the system does, and pretend we are SendMessage.
|
|
// Saves us some special casing in GodotTransmitMessage
|
|
return(GodotTransmitMessage(mtSendMessage, hWnd, Msg, wParam, lParam, 0, 0, 0, 0, 0, 0));
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=SendMessageW
|
|
Begin=
|
|
LRESULT __stdcall
|
|
GodotSendMessageW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
return(GodotTransmitMessage(mtSendMessage, hWnd, Msg, wParam, lParam, 0, 0, 0, 0, 0, 0));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=SendMessageCallbackW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotSendMessageCallbackW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam,
|
|
SENDASYNCPROC lpResultCallBack, ULONG_PTR dwData)
|
|
{
|
|
return(GodotTransmitMessage(mtSendMessageCallback, hWnd, Msg, wParam, lParam,
|
|
0, lpResultCallBack, dwData, 0, 0, 0));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=SendMessageTimeoutW
|
|
Begin=
|
|
LRESULT __stdcall
|
|
GodotSendMessageTimeoutW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam,
|
|
UINT fuFlags, UINT uTimeout, PDWORD_PTR lpdwResult)
|
|
{
|
|
return(GodotTransmitMessage(mtSendMessageTimeout, hWnd, Msg, wParam, lParam,
|
|
0, 0, 0, fuFlags, uTimeout, lpdwResult));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=SendNotifyMessageW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotSendNotifyMessageW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
return(GodotTransmitMessage(mtSendNotifyMessage, hWnd, Msg, wParam, lParam, 0, 0, 0, 0, 0, 0));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=SetCalendarInfoW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotSetCalendarInfoW(LCID Locale, CALID Calendar, CALTYPE CalType, LPCWSTR lpCalData)
|
|
{
|
|
if (s_pfnSetCalendarInfoA == NULL)
|
|
{
|
|
// Must allocate stuff for this API call
|
|
s_pfnSetCalendarInfoA = (PFNscia)GetKernelProc("SetCalendarInfoA");
|
|
}
|
|
|
|
if (s_pfnSetCalendarInfoA)
|
|
{
|
|
LPSTR lpCalDataAnsi;
|
|
UINT cpg;
|
|
UINT mcs;
|
|
|
|
if(CalType & CAL_USE_CP_ACP)
|
|
{
|
|
cpg = g_acp;
|
|
mcs = g_mcs;
|
|
}
|
|
else
|
|
{
|
|
cpg = CpgFromLocale(Locale);
|
|
mcs = CbPerChOfCpg(cpg);
|
|
}
|
|
|
|
GODOT_TO_CPG_STACKALLOC(lpCalData, lpCalDataAnsi, cpg, mcs);
|
|
|
|
return((s_pfnSetCalendarInfoA (Locale, Calendar, CalType, lpCalDataAnsi)));
|
|
}
|
|
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
return FALSE;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=SetClassLongW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotSetClassLongW(HWND hWnd, int nIndex, LONG dwNewLong)
|
|
{
|
|
DWORD RetVal;
|
|
|
|
if(nIndex != GCL_MENUNAME)
|
|
RetVal=SetClassLongA(hWnd, nIndex, dwNewLong);
|
|
else
|
|
{
|
|
LPSTR szNewLong;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(dwNewLong, szNewLong);
|
|
RetVal=SetClassLongA(hWnd, nIndex, (DWORD)szNewLong);
|
|
if(RetVal)
|
|
{
|
|
// We need to convert this string to Unicode and stick it in
|
|
// our global buffer, then return the pointer to that buffer.
|
|
// See comments at the dec. of m_wzMenuName for why things
|
|
// have to be done this way.
|
|
MultiByteToWideChar(g_acp, 0, (LPSTR)RetVal, -1, m_wzMenuName, 256);
|
|
RetVal = (DWORD)m_wzMenuName;
|
|
}
|
|
}
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=SetConsoleTitleW
|
|
Begin=
|
|
BOOL __stdcall GodotSetConsoleTitleW(LPCWSTR lpConsoleTitle)
|
|
{
|
|
LPSTR lpConsoleTitleAnsi;
|
|
|
|
GODOT_TO_CPG_STACKALLOC(lpConsoleTitle, lpConsoleTitleAnsi, g_oemcp, g_mcs);
|
|
|
|
return(SetConsoleTitleA(lpConsoleTitleAnsi));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=SetCurrentDirectoryW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotSetCurrentDirectoryW(LPCWSTR lpPathName)
|
|
{
|
|
LPSTR lpPathNameAnsi;
|
|
|
|
// Begin precall
|
|
GODOT_TO_CPG_STACKALLOC(lpPathName, lpPathNameAnsi, FILES_CPG, g_mcs);
|
|
|
|
return(SetCurrentDirectoryA(lpPathNameAnsi));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=SetJobW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotSetJobW(HANDLE hPrinter, DWORD JobId, DWORD Level, LPBYTE pJob, DWORD Command)
|
|
{
|
|
switch(Level)
|
|
{
|
|
case 0:
|
|
return(SetJobA(hPrinter, JobId, Level, pJob, Command));
|
|
break;
|
|
|
|
case 1:
|
|
{
|
|
JOB_INFO_1A ji1a;
|
|
LPJOB_INFO_1W lpji1 = (LPJOB_INFO_1W)pJob;
|
|
|
|
ji1a.JobId = lpji1->JobId;
|
|
GODOT_TO_ACP_STACKALLOC(lpji1->pPrinterName, ji1a.pPrinterName);
|
|
GODOT_TO_ACP_STACKALLOC(lpji1->pMachineName, ji1a.pMachineName);
|
|
GODOT_TO_ACP_STACKALLOC(lpji1->pUserName, ji1a.pUserName);
|
|
GODOT_TO_ACP_STACKALLOC(lpji1->pDocument, ji1a.pDocument);
|
|
GODOT_TO_ACP_STACKALLOC(lpji1->pDatatype, ji1a.pDatatype);
|
|
GODOT_TO_ACP_STACKALLOC(lpji1->pStatus, ji1a.pStatus);
|
|
ji1a.Status = lpji1->Status;
|
|
ji1a.Priority = lpji1->Priority;
|
|
ji1a.Position = lpji1->Position;
|
|
ji1a.TotalPages = lpji1->TotalPages;
|
|
ji1a.PagesPrinted = lpji1->PagesPrinted;
|
|
ji1a.Submitted = lpji1->Submitted;
|
|
return(SetJobA(hPrinter, JobId, Level, (LPBYTE)&ji1a, Command));
|
|
}
|
|
case 2:
|
|
{
|
|
JOB_INFO_2A ji2a;
|
|
LPJOB_INFO_2W lpji2 = (LPJOB_INFO_2W)pJob;
|
|
BOOL RetVal = FALSE;
|
|
|
|
ji2a.JobId = lpji2->JobId;
|
|
GODOT_TO_ACP_STACKALLOC(lpji2->pPrinterName, ji2a.pPrinterName);
|
|
GODOT_TO_ACP_STACKALLOC(lpji2->pMachineName, ji2a.pMachineName);
|
|
GODOT_TO_ACP_STACKALLOC(lpji2->pUserName, ji2a.pUserName);
|
|
GODOT_TO_ACP_STACKALLOC(lpji2->pNotifyName, ji2a.pNotifyName);
|
|
GODOT_TO_ACP_STACKALLOC(lpji2->pDocument, ji2a.pDocument);
|
|
GODOT_TO_ACP_STACKALLOC(lpji2->pDatatype, ji2a.pDatatype);
|
|
GODOT_TO_ACP_STACKALLOC(lpji2->pPrintProcessor, ji2a.pPrintProcessor);
|
|
GODOT_TO_ACP_STACKALLOC(lpji2->pParameters, ji2a.pParameters);
|
|
GODOT_TO_ACP_STACKALLOC(lpji2->pDriverName, ji2a.pDriverName);
|
|
GODOT_TO_ACP_STACKALLOC(lpji2->pStatus, ji2a.pStatus);
|
|
ji2a.pSecurityDescriptor = lpji2->pSecurityDescriptor;
|
|
ji2a.Status = lpji2->Status;
|
|
ji2a.Priority = lpji2->Priority;
|
|
ji2a.Position = lpji2->Position;
|
|
ji2a.StartTime = lpji2->StartTime;
|
|
ji2a.UntilTime = lpji2->UntilTime;
|
|
ji2a.TotalPages = lpji2->TotalPages;
|
|
ji2a.Size = lpji2->Size;
|
|
ji2a.Submitted = lpji2->Submitted;
|
|
ji2a.Time = lpji2->Time;
|
|
ji2a.PagesPrinted = lpji2->PagesPrinted;
|
|
|
|
if(lpji2->pDevMode)
|
|
{
|
|
ji2a.pDevMode = GodotHeapAlloc(sizeof(DEVMODEA) + lpji2->pDevMode->dmDriverExtra);
|
|
if(ji2a.pDevMode==NULL)
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(FALSE);
|
|
}
|
|
ZeroMemory(ji2a.pDevMode, sizeof(DEVMODEA) + lpji2->pDevMode->dmDriverExtra);
|
|
DevModeAfromW(ji2a.pDevMode, lpji2->pDevMode);
|
|
}
|
|
|
|
RetVal = SetJobA(hPrinter, JobId, Level, (LPBYTE)&ji2a, Command);
|
|
|
|
if(lpji2->pDevMode && ji2a.pDevMode)
|
|
GodotHeapFree(ji2a.pDevMode);
|
|
|
|
return(RetVal);
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return(FALSE);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=SetLocaleInfoW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotSetLocaleInfoW(LCID Locale, LCTYPE LCType, LPCWSTR lpLCData)
|
|
{
|
|
LPSTR lpLCDataAnsi;
|
|
UINT cpg;
|
|
UINT mcs;
|
|
|
|
// Begin precall
|
|
if (LCType & LOCALE_USE_CP_ACP)
|
|
{
|
|
// Win9x accepts LOCALE_USE_CP_ACP, so we need to treat the
|
|
// flag properly and use it for any/all mapping if the user
|
|
// requests it.
|
|
cpg = g_acp;
|
|
mcs = g_mcs;
|
|
}
|
|
else
|
|
{
|
|
cpg = CpgFromLocale(Locale);
|
|
mcs = CbPerChOfCpg(cpg);
|
|
}
|
|
|
|
GODOT_TO_CPG_STACKALLOC(lpLCData, lpLCDataAnsi, cpg, mcs);
|
|
if(lpLCDataAnsi==NULL)
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
return(SetLocaleInfoA(Locale, LCType, lpLCDataAnsi));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=SetMenuItemInfoW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotSetMenuItemInfoW(HMENU hMenu, UINT uItem, BOOL fByPosition, LPCMENUITEMINFOW lpmiiw)
|
|
{
|
|
MENUITEMINFOA miia;
|
|
BOOL RetVal;
|
|
BOOL fAlloc = MenuItemInfoAfromW(&miia, lpmiiw);
|
|
|
|
RetVal = SetMenuItemInfoA(hMenu, uItem, fByPosition, &miia);
|
|
if(fAlloc)
|
|
GodotHeapFree(miia.dwTypeData);
|
|
return(RetVal);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=SetPrinterW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotSetPrinterW(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, DWORD Command)
|
|
{
|
|
switch(Level)
|
|
{
|
|
case 0:
|
|
{
|
|
return(SetPrinterA(hPrinter, Level, pPrinter, Command));
|
|
break;
|
|
}
|
|
|
|
case 2:
|
|
{
|
|
PRINTER_INFO_2A pi2a;
|
|
LPPRINTER_INFO_2W lppi2 = (LPPRINTER_INFO_2W)pPrinter;
|
|
BOOL RetVal = FALSE;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lppi2->pServerName, pi2a.pServerName);
|
|
GODOT_TO_ACP_STACKALLOC(lppi2->pPrinterName, pi2a.pPrinterName);
|
|
GODOT_TO_ACP_STACKALLOC(lppi2->pShareName, pi2a.pShareName);
|
|
GODOT_TO_ACP_STACKALLOC(lppi2->pPortName, pi2a.pPortName);
|
|
GODOT_TO_ACP_STACKALLOC(lppi2->pDriverName, pi2a.pDriverName);
|
|
GODOT_TO_ACP_STACKALLOC(lppi2->pComment, pi2a.pComment);
|
|
GODOT_TO_ACP_STACKALLOC(lppi2->pLocation, pi2a.pLocation);
|
|
if((!pi2a.pServerName && lppi2->pServerName) ||
|
|
(!pi2a.pPrinterName && lppi2->pPrinterName) ||
|
|
(!pi2a.pShareName && lppi2->pShareName) ||
|
|
(!pi2a.pPortName && lppi2->pPortName) ||
|
|
(!pi2a.pDriverName && lppi2->pDriverName) ||
|
|
(!pi2a.pComment && lppi2->pComment) ||
|
|
(!pi2a.pLocation && lppi2->pLocation))
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lppi2->pSepFile, pi2a.pSepFile);
|
|
GODOT_TO_ACP_STACKALLOC(lppi2->pPrintProcessor, pi2a.pPrintProcessor);
|
|
GODOT_TO_ACP_STACKALLOC(lppi2->pDatatype, pi2a.pDatatype);
|
|
GODOT_TO_ACP_STACKALLOC(lppi2->pParameters, pi2a.pParameters);
|
|
if((!pi2a.pSepFile && lppi2->pSepFile) ||
|
|
(!pi2a.pPrintProcessor && lppi2->pPrintProcessor) ||
|
|
(!pi2a.pDatatype && lppi2->pDatatype) ||
|
|
(!pi2a.pParameters && lppi2->pParameters))
|
|
{
|
|
return(FALSE);
|
|
}
|
|
pi2a.pSecurityDescriptor = lppi2->pSecurityDescriptor;
|
|
pi2a.Attributes = lppi2->Attributes;
|
|
pi2a.Priority = lppi2->Priority;
|
|
pi2a.DefaultPriority = lppi2->DefaultPriority;
|
|
pi2a.StartTime = lppi2->StartTime;
|
|
pi2a.UntilTime = lppi2->UntilTime;
|
|
pi2a.Status = lppi2->Status;
|
|
pi2a.cJobs = lppi2->cJobs;
|
|
pi2a.AveragePPM = lppi2->AveragePPM;
|
|
|
|
if(lppi2->pDevMode)
|
|
{
|
|
pi2a.pDevMode = GodotHeapAlloc(sizeof(DEVMODEA) + lppi2->pDevMode->dmDriverExtra);
|
|
if(pi2a.pDevMode==NULL)
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(FALSE);
|
|
}
|
|
ZeroMemory(pi2a.pDevMode, sizeof(DEVMODEA) + lppi2->pDevMode->dmDriverExtra);
|
|
DevModeAfromW(pi2a.pDevMode, lppi2->pDevMode);
|
|
}
|
|
|
|
RetVal = SetPrinterA(hPrinter, Level, (LPBYTE)&pi2a, Command);
|
|
|
|
if(lppi2->pDevMode && pi2a.pDevMode)
|
|
GodotHeapFree(pi2a.pDevMode);
|
|
|
|
return(RetVal);
|
|
break;
|
|
}
|
|
|
|
case 5:
|
|
{
|
|
PRINTER_INFO_5A pi5a;
|
|
LPPRINTER_INFO_5W lppi5 = (LPPRINTER_INFO_5W)pPrinter;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lppi5->pPrinterName, pi5a.pPrinterName);
|
|
GODOT_TO_ACP_STACKALLOC(lppi5->pPortName, pi5a.pPortName);
|
|
if((!pi5a.pPrinterName && lppi5->pPrinterName) ||
|
|
(!pi5a.pPortName && lppi5->pPortName))
|
|
{
|
|
return(FALSE);
|
|
}
|
|
pi5a.Attributes = lppi5->Attributes;
|
|
pi5a.DeviceNotSelectedTimeout = lppi5->DeviceNotSelectedTimeout;
|
|
pi5a.TransmissionRetryTimeout = lppi5->TransmissionRetryTimeout;
|
|
return(SetPrinterA(hPrinter, Level, (LPBYTE)&pi5a, Command));
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return(FALSE);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=SetPrinterDataW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotSetPrinterDataW(HANDLE hPrinter, LPWSTR pValueName, DWORD Type, LPBYTE pData, DWORD cbData)
|
|
{
|
|
LPSTR pValueNameAnsi;
|
|
LPSTR pDataAnsi;
|
|
size_t cchData;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(pValueName, pValueNameAnsi);
|
|
if(!pValueNameAnsi && pValueName)
|
|
return(0);
|
|
|
|
switch(Type)
|
|
{
|
|
case REG_MULTI_SZ:
|
|
if (FSTRING_VALID((LPWSTR)pData))
|
|
{
|
|
// Lets go for the minimal buffer we can reasonably get away with
|
|
cchData = gwcslen((LPWSTR)pData);
|
|
|
|
// Convert the information to ANSI and call the API with it
|
|
_STACKALLOC((cchData * g_mcs) + 1, pDataAnsi);
|
|
if(!pDataAnsi)
|
|
{
|
|
return(ERROR_STACK_OVERFLOW);
|
|
}
|
|
ZeroMemory(pDataAnsi, (cchData * g_mcs) + 1);
|
|
WideCharToMultiByte(g_acp,
|
|
0,
|
|
(LPWSTR)pData,
|
|
(cbData / sizeof(WCHAR)),
|
|
pDataAnsi,
|
|
(cchData * g_mcs) + 1,
|
|
NULL,
|
|
NULL);
|
|
}
|
|
else
|
|
pDataAnsi = (LPSTR)pData;
|
|
|
|
return(SetPrinterDataA(hPrinter,
|
|
pValueNameAnsi,
|
|
Type,
|
|
(LPBYTE)pDataAnsi,
|
|
lstrlenA(pDataAnsi)));
|
|
break;
|
|
|
|
case REG_SZ:
|
|
case REG_EXPAND_SZ:
|
|
if (FSTRING_VALID((LPWSTR)pData))
|
|
{
|
|
// Lets go for the minimal buffer we can reasonably get away with
|
|
cchData = cchUnicodeMultiSz((LPWSTR)pData);
|
|
|
|
// Convert the information to ANSI and call the API with it
|
|
_STACKALLOC((cchData * g_mcs) + 1, pDataAnsi);
|
|
if(pDataAnsi==NULL)
|
|
{
|
|
return(0);
|
|
}
|
|
WideCharToMultiByte(g_acp, 0,
|
|
(LPWSTR)pData, (cbData / sizeof(WCHAR)),
|
|
(LPSTR)pDataAnsi, (cchData * g_mcs),
|
|
NULL, NULL);
|
|
}
|
|
else
|
|
pDataAnsi = (LPSTR)pData;
|
|
|
|
return(SetPrinterDataA(hPrinter, pValueNameAnsi, Type,
|
|
(LPBYTE)pDataAnsi, cbAnsiMultiSz(pDataAnsi)));
|
|
break;
|
|
|
|
default:
|
|
|
|
return(SetPrinterDataA(hPrinter, pValueNameAnsi, Type, pData, cbData));
|
|
break;
|
|
}
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=SetPropA
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotSetPropA(HWND hWnd, LPCSTR lpString, HANDLE hData)
|
|
{
|
|
if(IsInternalWindowProperty((LPWSTR)lpString, FALSE))
|
|
return(FALSE);
|
|
|
|
return(SetPropA(hWnd, lpString, hData));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=SetPropW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotSetPropW(HWND hWnd, LPCWSTR lpString, HANDLE hData)
|
|
{
|
|
LPSTR lpStringAnsi;
|
|
|
|
if(IsInternalWindowProperty(lpString, TRUE))
|
|
return(FALSE);
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lpString, lpStringAnsi);
|
|
if(!lpStringAnsi && lpString)
|
|
return(0);
|
|
|
|
return(SetPropA(hWnd, lpStringAnsi, hData));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=SetVolumeLabelW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotSetVolumeLabelW(LPCWSTR lpRootPathName, LPCWSTR lpVolumeName)
|
|
{
|
|
LPSTR lpRootPathNameAnsi;
|
|
LPSTR lpVolumeNameAnsi;
|
|
UINT cpg = FILES_CPG;
|
|
|
|
// Begin precall
|
|
GODOT_TO_CPG_STACKALLOC(lpRootPathName, lpRootPathNameAnsi, cpg, g_mcs);
|
|
GODOT_TO_CPG_STACKALLOC(lpVolumeName, lpVolumeNameAnsi, cpg, g_mcs);
|
|
|
|
return(SetVolumeLabelA(lpRootPathNameAnsi, lpVolumeNameAnsi));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=SetWindowsHookA
|
|
Begin=
|
|
HHOOK __stdcall
|
|
GodotSetWindowsHookA(int nFilterType, HOOKPROC pfnFilterProc)
|
|
{
|
|
// CONSIDER: Support Hook functions? This is a tough one!
|
|
// This [EFunc] is not even hooked up at the moment.
|
|
return(SetWindowsHookA(nFilterType, pfnFilterProc));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=SetWindowsHookW
|
|
Begin=
|
|
HHOOK __stdcall
|
|
GodotSetWindowsHookW(int nFilterType, HOOKPROC pfnFilterProc)
|
|
{
|
|
// CONSIDER: Support Hook functions? This is a tough one!
|
|
return(SetWindowsHookA(nFilterType, pfnFilterProc));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=SetWindowsHookExA
|
|
Begin=
|
|
HHOOK __stdcall
|
|
GodotSetWindowsHookExA(int idHook, HOOKPROC lpfn, HINSTANCE hmod, DWORD dwThreadId)
|
|
{
|
|
// CONSIDER: Support Hook functions? This is a tough one!
|
|
// This [EFunc] is not even hooked up at the moment.
|
|
return(SetWindowsHookExA(idHook, lpfn, hmod, dwThreadId));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=SetWindowsHookExW
|
|
Begin=
|
|
HHOOK __stdcall
|
|
GodotSetWindowsHookExW(int idHook, HOOKPROC lpfn, HINSTANCE hmod, DWORD dwThreadId)
|
|
{
|
|
// CONSIDER: Support Hook functions? This is a tough one!
|
|
return(SetWindowsHookExA(idHook, lpfn, hmod, dwThreadId));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=SetWindowLongA
|
|
Begin=
|
|
LONG __stdcall
|
|
GodotSetWindowLongA(HWND hWnd, int nIndex, LONG dwNewLong)
|
|
{
|
|
return(SetWindowLongInternal(hWnd, nIndex, dwNewLong, FALSE));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=SetWindowLongW
|
|
Begin=
|
|
LONG __stdcall
|
|
GodotSetWindowLongW(HWND hWnd, int nIndex, LONG dwNewLong)
|
|
{
|
|
return(SetWindowLongInternal(hWnd, nIndex, dwNewLong, TRUE));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=SetWindowTextW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotSetWindowTextW(HWND hWnd, LPCWSTR lpString)
|
|
{
|
|
BOOL RetVal;
|
|
LPSTR lpStringAnsi = NULL;
|
|
ALLOCRETURN ar = GodotToAcpOnHeap(lpString, &lpStringAnsi);
|
|
|
|
if(ar==arFailed)
|
|
RetVal = FALSE;
|
|
else
|
|
RetVal = SetWindowTextA(hWnd, lpStringAnsi);
|
|
|
|
if(ar==arAlloc)
|
|
GodotHeapFree(lpStringAnsi);
|
|
return(RetVal);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=ShellAboutW
|
|
Begin=
|
|
INT __stdcall
|
|
GodotShellAboutW(HWND hWnd, LPCWSTR szApp, LPCWSTR szOtherStuff, HICON hIcon)
|
|
{
|
|
LPSTR szAppAnsi;
|
|
LPSTR szOtherStuffAnsi;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(szApp, szAppAnsi);
|
|
GODOT_TO_ACP_STACKALLOC(szOtherStuff, szOtherStuffAnsi);
|
|
if((!szAppAnsi && szApp) ||
|
|
(!szOtherStuffAnsi && szOtherStuff))
|
|
return(0);
|
|
|
|
return(ShellAboutA(hWnd, szAppAnsi, szOtherStuffAnsi, hIcon));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=SHChangeNotify
|
|
Begin=
|
|
|
|
// uFlags & SHCNF_TYPE is an ID which indicates what dwItem1 and dwItem2 mean
|
|
#define SHCNF_IDLIST 0x0000 // LPITEMIDLIST
|
|
#define SHCNF_PATHA 0x0001 // path name
|
|
#define SHCNF_PRINTERA 0x0002 // printer friendly name
|
|
#define SHCNF_DWORD 0x0003 // DWORD
|
|
#define SHCNF_PRINTJOBA 0x0004 // dwItem1: printer name
|
|
// dwItem2: SHCNF_PRINTJOB_DATA
|
|
#define SHCNF_PATHW 0x0005 // path name
|
|
#define SHCNF_PRINTERW 0x0006 // printer friendly name
|
|
#define SHCNF_PRINTJOBW 0x0007 // dwItem1: printer name
|
|
// dwItem2: SHCNF_PRINTJOB_DATA
|
|
#define SHCNF_TYPE 0x00FF
|
|
#define SHCNF_FLUSH 0x1000
|
|
#define SHCNF_FLUSHNOWAIT 0x2000
|
|
|
|
#define SHCNF_HAS_WSTR_PARAMS(f) ((f & SHCNF_TYPE) == SHCNF_PATHW || \
|
|
(f & SHCNF_TYPE) == SHCNF_PRINTERW || \
|
|
(f & SHCNF_TYPE) == SHCNF_PRINTJOBW )
|
|
|
|
void __stdcall
|
|
GodotSHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
|
|
{
|
|
if(!SHCNF_HAS_WSTR_PARAMS(uFlags))
|
|
{
|
|
SHChangeNotify(wEventId, uFlags, dwItem1, dwItem2);
|
|
}
|
|
else
|
|
{
|
|
LPSTR dwItem1Ansi, dwItem2Ansi;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(dwItem1, dwItem1Ansi);
|
|
GODOT_TO_ACP_STACKALLOC(dwItem2, dwItem2Ansi);
|
|
|
|
// Munge flags to ANSI types based on
|
|
// the Unicode types that are there now
|
|
if ((uFlags & SHCNF_TYPE) == SHCNF_PATHW)
|
|
{
|
|
uFlags = (uFlags & ~SHCNF_TYPE) | SHCNF_PATHA;
|
|
}
|
|
else if ((uFlags & SHCNF_TYPE) == SHCNF_PRINTERW)
|
|
{
|
|
uFlags = (uFlags & ~SHCNF_TYPE) | SHCNF_PRINTERA;
|
|
}
|
|
else
|
|
{
|
|
uFlags = (uFlags & ~SHCNF_TYPE) | SHCNF_PRINTJOBA;
|
|
}
|
|
|
|
SHChangeNotify(wEventId, uFlags, (void*)dwItem1Ansi, (void*)dwItem2Ansi);
|
|
}
|
|
return ;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=ShellExecuteW
|
|
Begin=
|
|
HINSTANCE __stdcall
|
|
GodotShellExecuteW( HWND hwnd,
|
|
LPCWSTR lpOperation,
|
|
LPCWSTR lpFile,
|
|
LPCWSTR lpParameters,
|
|
LPCWSTR lpDirectory,
|
|
INT nShowCmd
|
|
)
|
|
{
|
|
LPSTR lpOperationAnsi, lpFileAnsi, lpParametersAnsi, lpDirectoryAnsi;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lpOperation, lpOperationAnsi);
|
|
GODOT_TO_ACP_STACKALLOC(lpFile, lpFileAnsi);
|
|
GODOT_TO_ACP_STACKALLOC(lpParameters, lpParametersAnsi);
|
|
GODOT_TO_ACP_STACKALLOC(lpDirectory, lpDirectoryAnsi);
|
|
if((!lpOperationAnsi && lpOperation) ||
|
|
(!lpFileAnsi && lpFile) ||
|
|
(!lpParametersAnsi && lpParameters) ||
|
|
(!lpDirectoryAnsi && lpDirectory))
|
|
return(0);
|
|
|
|
return(ShellExecuteA(hwnd, lpOperationAnsi, lpFileAnsi, lpParametersAnsi, lpDirectoryAnsi, nShowCmd));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=ShellExecuteExW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotShellExecuteExW(LPSHELLEXECUTEINFOW lpsei)
|
|
{
|
|
SHELLEXECUTEINFOA seia;
|
|
size_t lpFileLength;
|
|
BOOL RetVal;
|
|
|
|
ZeroMemory(&seia, sizeof(SHELLEXECUTEINFOA));
|
|
seia.cbSize = sizeof(SHELLEXECUTEINFOA);
|
|
seia.fMask = lpsei->fMask;
|
|
seia.hwnd = lpsei->hwnd;
|
|
seia.nShow = lpsei->nShow;
|
|
seia.hInstApp = lpsei->hInstApp;
|
|
seia.lpIDList = lpsei->lpIDList;
|
|
seia.hkeyClass = lpsei->hkeyClass;
|
|
seia.dwHotKey = lpsei->dwHotKey;
|
|
seia.hIcon = lpsei->hIcon;
|
|
seia.hProcess = lpsei->hProcess;
|
|
lpFileLength = cchUnicodeMultiSz(lpsei->lpFile);
|
|
_STACKALLOC(lpFileLength, seia.lpFile);
|
|
GODOT_TO_ACP_STACKALLOC(lpsei->lpVerb, seia.lpVerb);
|
|
GODOT_TO_ACP_STACKALLOC(lpsei->lpParameters, seia.lpParameters);
|
|
GODOT_TO_ACP_STACKALLOC(lpsei->lpDirectory, seia.lpDirectory);
|
|
GODOT_TO_ACP_STACKALLOC(lpsei->lpClass, seia.lpClass);
|
|
WideCharToMultiByte(g_acp, 0,
|
|
lpsei->lpFile, lpFileLength,
|
|
(LPSTR)(seia.lpFile), lpFileLength,
|
|
NULL, NULL);
|
|
RetVal = ShellExecuteExA(&seia);
|
|
|
|
lpsei->hInstApp = seia.hInstApp;
|
|
lpsei->hProcess = seia.hProcess;
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=Shell_NotifyIconW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotShell_NotifyIconW(DWORD dwMessage, PNOTIFYICONDATAW lpData)
|
|
{
|
|
PNOTIFYICONDATAA pnida;
|
|
|
|
if (lpData->cbSize == (UINT)NOTIFYICONDATAW_V1_SIZE)
|
|
{
|
|
// Old structure
|
|
_STACKALLOC(NOTIFYICONDATAA_V1_SIZE, pnida);
|
|
if(pnida)
|
|
{
|
|
ZeroMemory(pnida, NOTIFYICONDATAA_V1_SIZE);
|
|
pnida->cbSize = NOTIFYICONDATAA_V1_SIZE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// New structure
|
|
_STACKALLOC(sizeof(NOTIFYICONDATA), pnida);
|
|
if(pnida)
|
|
{
|
|
ZeroMemory(pnida, sizeof(NOTIFYICONDATA));
|
|
pnida->cbSize = sizeof(NOTIFYICONDATA);
|
|
pnida->dwState = lpData->dwState;
|
|
pnida->dwStateMask = lpData->dwStateMask;
|
|
pnida->uTimeout = lpData->uTimeout;
|
|
pnida->dwInfoFlags = lpData->dwInfoFlags;
|
|
WideCharToMultiByte(g_acp, 0, lpData->szInfo, 256, pnida->szInfo, 256, NULL, NULL);
|
|
WideCharToMultiByte(g_acp, 0, lpData->szInfoTitle, 64, pnida->szInfoTitle, 64, NULL, NULL);
|
|
}
|
|
}
|
|
|
|
// Members common to both structures
|
|
if(pnida)
|
|
{
|
|
pnida->hWnd = lpData->hWnd;
|
|
pnida->uID = lpData->uID;
|
|
pnida->uFlags = lpData->uFlags;
|
|
pnida->uCallbackMessage = lpData->uCallbackMessage;
|
|
pnida->hIcon = lpData->hIcon;
|
|
WideCharToMultiByte(g_acp, 0, lpData->szTip, 64, pnida->szTip, 64, NULL, NULL);
|
|
|
|
// Call the 'A' version of the API
|
|
return(Shell_NotifyIconA(dwMessage, pnida));
|
|
}
|
|
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(FALSE);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=SHBrowseForFolderW
|
|
Begin=
|
|
LPITEMIDLIST _stdcall
|
|
GodotSHBrowseForFolderW(LPBROWSEINFOW lpbi)
|
|
{
|
|
char buf[_MAX_PATH];
|
|
BROWSEINFOA bi;
|
|
LPITEMIDLIST item;
|
|
|
|
bi.hwndOwner = lpbi->hwndOwner;
|
|
bi.pidlRoot = lpbi->pidlRoot;
|
|
bi.pszDisplayName = buf;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lpbi->lpszTitle, bi.lpszTitle);
|
|
bi.ulFlags = lpbi->ulFlags;
|
|
bi.lpfn = lpbi->lpfn;
|
|
bi.lParam = lpbi->lParam;
|
|
bi.iImage = lpbi->iImage;
|
|
|
|
if(item = SHBrowseForFolderA(&bi))
|
|
{
|
|
MultiByteToWideChar(g_acp, 0, bi.pszDisplayName, -1, lpbi->pszDisplayName, _MAX_PATH);
|
|
lpbi->iImage = bi.iImage;
|
|
}
|
|
return item;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=SHFileOperationW
|
|
Begin=
|
|
int __stdcall
|
|
GodotSHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp)
|
|
{
|
|
SHFILEOPSTRUCTA sfoa;
|
|
size_t cch;
|
|
|
|
ZeroMemory(&sfoa, sizeof(SHFILEOPSTRUCTA));
|
|
|
|
sfoa.hwnd = lpFileOp->hwnd;
|
|
sfoa.wFunc = lpFileOp->wFunc;
|
|
sfoa.fFlags = lpFileOp->fFlags;
|
|
sfoa.fAnyOperationsAborted = lpFileOp->fAnyOperationsAborted;
|
|
sfoa.hNameMappings = lpFileOp->hNameMappings;
|
|
|
|
cch = cchUnicodeMultiSz(lpFileOp->pFrom);
|
|
if(cch)
|
|
{
|
|
_STACKALLOC((cch*g_mcs + 1), sfoa.pFrom);
|
|
if(!sfoa.pFrom)
|
|
{
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(1);
|
|
}
|
|
ZeroMemory((LPSTR)sfoa.pFrom, (cch*g_mcs + 1));
|
|
WideCharToMultiByte(g_acp, 0, lpFileOp->pFrom, cch, (LPSTR)sfoa.pFrom, cch*g_mcs, NULL, NULL);
|
|
}
|
|
|
|
cch = cchUnicodeMultiSz(lpFileOp->pTo);
|
|
if(cch)
|
|
{
|
|
_STACKALLOC((cch*g_mcs + 1), sfoa.pTo);
|
|
if(!sfoa.pTo)
|
|
{
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(1);
|
|
}
|
|
ZeroMemory((LPSTR)sfoa.pTo, (cch*g_mcs + 1));
|
|
WideCharToMultiByte(g_acp, 0, lpFileOp->pTo, cch, (LPSTR)sfoa.pTo, cch*g_mcs, NULL, NULL);
|
|
}
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lpFileOp->lpszProgressTitle, sfoa.lpszProgressTitle);
|
|
|
|
return(SHFileOperationA(&sfoa));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=SHGetFileInfoW
|
|
Begin=
|
|
DWORD_PTR __stdcall
|
|
GodotSHGetFileInfoW(LPCWSTR pszPath, DWORD dwFileAttribs, SHFILEINFOW * psfi, UINT cbFileInfo, UINT uFlags)
|
|
{
|
|
// Begin locals
|
|
DWORD_PTR RetVal;
|
|
CHAR pszPathAnsi[_MAX_PATH];
|
|
SHFILEINFOA sfia;
|
|
|
|
ZeroMemory(&sfia, sizeof(SHFILEINFOA));
|
|
|
|
// If SHGFI_ATTR_SPECIFIED is among uFlags, dwAttributes is taken from the structure
|
|
// We simply initialize it in every case (assuming a pointer was supplied)
|
|
if (psfi)
|
|
sfia.dwAttributes = psfi->dwAttributes;
|
|
|
|
// If SHGFI_PIDL is specified, pszPath is actually a pointer to an ITEMIDLIST.
|
|
// Otherwise, convert the string from wide to MBCS
|
|
if (!(uFlags & SHGFI_PIDL))
|
|
{
|
|
WideCharToMultiByte(g_acp, 0, pszPath, _MAX_PATH, pszPathAnsi, _MAX_PATH, NULL, NULL);
|
|
RetVal=SHGetFileInfoA(pszPathAnsi, dwFileAttribs, &sfia, sizeof(SHFILEINFOA), uFlags);
|
|
}
|
|
else
|
|
RetVal=SHGetFileInfoA((LPSTR)pszPath, dwFileAttribs, &sfia, sizeof(SHFILEINFOA), uFlags);
|
|
|
|
if (RetVal && psfi)
|
|
{
|
|
psfi->hIcon = sfia.hIcon;
|
|
psfi->iIcon = sfia.iIcon;
|
|
psfi->dwAttributes = sfia.dwAttributes;
|
|
|
|
if ((uFlags & (SHGFI_DISPLAYNAME | SHGFI_ICONLOCATION)) && sfia.szDisplayName)
|
|
MultiByteToWideChar(g_acp, 0, sfia.szDisplayName, -1, psfi->szDisplayName, _MAX_PATH);
|
|
else
|
|
psfi->szDisplayName[0] = '\0';
|
|
|
|
if ((uFlags & SHGFI_TYPENAME) && sfia.szTypeName)
|
|
MultiByteToWideChar(g_acp, 0, sfia.szTypeName, -1, psfi->szTypeName, 80);
|
|
else
|
|
psfi->szTypeName[0] = '\0';
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=SHGetNewLinkInfoW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotSHGetNewLinkInfoW(LPCWSTR pszLinkTo, LPCWSTR pszDir, LPWSTR pszName, BOOL * pfMustCopy, UINT uFlags)
|
|
{
|
|
BOOL RetVal;
|
|
LPSTR pszDirAnsi;
|
|
char * pszNameAnsi[_MAX_PATH];
|
|
|
|
GODOT_TO_ACP_STACKALLOC(pszDir, pszDirAnsi);
|
|
if(uFlags & SHGNLI_PIDL)
|
|
RetVal=SHGetNewLinkInfoA((LPCSTR)pszLinkTo, pszDirAnsi, (LPSTR)pszNameAnsi, pfMustCopy, uFlags);
|
|
else
|
|
{
|
|
LPSTR pszLinkToAnsi;
|
|
GODOT_TO_ACP_STACKALLOC(pszLinkTo, pszLinkToAnsi);
|
|
RetVal=SHGetNewLinkInfoA(pszLinkToAnsi, pszDirAnsi, (LPSTR)pszNameAnsi, pfMustCopy, uFlags);
|
|
}
|
|
|
|
if(RetVal)
|
|
MultiByteToWideChar(g_acp, 0, (LPSTR)pszNameAnsi, -1, pszName, _MAX_PATH);
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=SHGetPathFromIDListW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotSHGetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath)
|
|
{
|
|
char buf[_MAX_PATH];
|
|
BOOL fRet;
|
|
|
|
if(fRet = SHGetPathFromIDListA(pidl, buf))
|
|
{
|
|
MultiByteToWideChar(g_acp, 0, buf, -1, pszPath, _MAX_PATH);
|
|
}
|
|
return fRet;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=sndPlaySoundW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotsndPlaySoundW(LPCWSTR pszSound, UINT fuSound)
|
|
{
|
|
BOOL RetVal;
|
|
LPSTR pszSoundAnsi;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(pszSound, pszSoundAnsi);
|
|
|
|
RetVal=sndPlaySoundA(pszSoundAnsi, fuSound);
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=StartDocW
|
|
Begin=
|
|
int __stdcall
|
|
GodotStartDocW(HDC hdc, const DOCINFOW * lpdi)
|
|
{
|
|
if(lpdi==NULL)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return(0);
|
|
}
|
|
else
|
|
{
|
|
DOCINFOA dia;
|
|
int RetVal;
|
|
UINT cpg = CpgFromHdc(hdc);
|
|
UINT mcs = CbPerChOfCpg(cpg);
|
|
|
|
// Begin precall
|
|
ZeroMemory(&dia, sizeof(DOCINFOA));
|
|
dia.cbSize = sizeof(DOCINFOA);
|
|
GODOT_TO_CPG_STACKALLOC(lpdi->lpszDocName, dia.lpszDocName, cpg, mcs);
|
|
GODOT_TO_CPG_STACKALLOC(lpdi->lpszOutput, dia.lpszOutput, cpg, mcs);
|
|
GODOT_TO_CPG_STACKALLOC(lpdi->lpszDatatype, dia.lpszDatatype, cpg, mcs);
|
|
dia.fwType = lpdi->fwType;
|
|
|
|
RetVal = StartDocA(hdc, &dia);
|
|
return(RetVal);
|
|
}
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=StartDocPrinterW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotStartDocPrinterW(HANDLE hPrinter, DWORD Level, LPBYTE pDocInfo)
|
|
{
|
|
DOC_INFO_2A dcia;
|
|
|
|
switch(Level)
|
|
{
|
|
case 2:
|
|
dcia.dwMode = ((LPDOC_INFO_2W)pDocInfo)->dwMode;
|
|
dcia.JobId = ((LPDOC_INFO_2W)pDocInfo)->JobId;
|
|
|
|
// fall through to pick up the strings that are shared
|
|
|
|
case 1:
|
|
GODOT_TO_ACP_STACKALLOC(((LPDOC_INFO_1W)pDocInfo)->pDocName, dcia.pDocName);
|
|
GODOT_TO_ACP_STACKALLOC(((LPDOC_INFO_1W)pDocInfo)->pOutputFile, dcia.pOutputFile);
|
|
GODOT_TO_ACP_STACKALLOC(((LPDOC_INFO_1W)pDocInfo)->pDatatype, dcia.pDatatype);
|
|
break;
|
|
|
|
default:
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return(0);
|
|
break;
|
|
}
|
|
|
|
return(StartDocPrinterA(hPrinter, Level, (LPBYTE)&dcia));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=TextOutW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotTextOutW(HDC hdc, int nXStart, int nYStart, LPCWSTR lpString, int cbString)
|
|
{
|
|
// Office does this too: why call TextOutW and have
|
|
// to work around the Win9x bug twice, after all?
|
|
return GodotExtTextOutW(hdc, nXStart, nYStart, 0, NULL, lpString, cbString, NULL);
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=SystemParametersInfoW
|
|
Begin=
|
|
BOOL __stdcall GodotSystemParametersInfoW(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni)
|
|
{
|
|
BOOL RetVal = FALSE; // guilty until proven innocent
|
|
|
|
// About 1/3 of this code is stolen from VSANSI, but they skip too
|
|
// many uiParams to suit our full needs.
|
|
|
|
// APP COMPAT: It seems that Win9x does not require that uiParam set the size if
|
|
// cbSize does, so we need to let them live with this. If either value is set properly,
|
|
// then let them on through.
|
|
|
|
switch(uiAction)
|
|
{
|
|
case SPI_GETNONCLIENTMETRICS:
|
|
case SPI_SETNONCLIENTMETRICS:
|
|
{
|
|
PNONCLIENTMETRICSW pncmw = (PNONCLIENTMETRICSW)pvParam;
|
|
|
|
if(pncmw &&
|
|
((pncmw->cbSize == sizeof(NONCLIENTMETRICSW)) ||
|
|
(uiParam == sizeof(NONCLIENTMETRICSW))))
|
|
{
|
|
NONCLIENTMETRICSA ncma;
|
|
ncma.cbSize = sizeof(NONCLIENTMETRICSA);
|
|
|
|
if(uiAction == SPI_SETNONCLIENTMETRICS)
|
|
{
|
|
ncma.iBorderWidth = pncmw->iBorderWidth;
|
|
ncma.iScrollWidth = pncmw->iScrollWidth;
|
|
ncma.iScrollHeight = pncmw->iScrollHeight;
|
|
ncma.iCaptionWidth = pncmw->iCaptionWidth;
|
|
ncma.iCaptionHeight = pncmw->iCaptionHeight;
|
|
LogFontAfromW(&ncma.lfCaptionFont, &pncmw->lfCaptionFont);
|
|
ncma.iSmCaptionWidth = pncmw->iSmCaptionWidth;
|
|
ncma.iSmCaptionHeight = pncmw->iSmCaptionHeight;
|
|
LogFontAfromW(&ncma.lfSmCaptionFont, &pncmw->lfSmCaptionFont);
|
|
ncma.iMenuWidth = pncmw->iMenuWidth;
|
|
ncma.iMenuHeight = pncmw->iMenuHeight;
|
|
LogFontAfromW(&ncma.lfMenuFont, &pncmw->lfMenuFont);
|
|
LogFontAfromW(&ncma.lfStatusFont, &pncmw->lfStatusFont);
|
|
LogFontAfromW(&ncma.lfMessageFont, &pncmw->lfMessageFont);
|
|
}
|
|
|
|
RetVal = SystemParametersInfoA(uiAction, sizeof(NONCLIENTMETRICSA), &ncma, fWinIni);
|
|
|
|
if(RetVal &&
|
|
(uiAction == SPI_GETNONCLIENTMETRICS))
|
|
{
|
|
pncmw->cbSize = sizeof(NONCLIENTMETRICSW);
|
|
pncmw->iBorderWidth = ncma.iBorderWidth;
|
|
pncmw->iScrollWidth = ncma.iScrollWidth;
|
|
pncmw->iScrollHeight = ncma.iScrollHeight;
|
|
pncmw->iCaptionWidth = ncma.iCaptionWidth;
|
|
pncmw->iCaptionHeight = ncma.iCaptionHeight;
|
|
LogFontWfromA(&pncmw->lfCaptionFont, &ncma.lfCaptionFont);
|
|
pncmw->iSmCaptionWidth = ncma.iSmCaptionWidth;
|
|
pncmw->iSmCaptionHeight = ncma.iSmCaptionHeight;
|
|
LogFontWfromA(&pncmw->lfSmCaptionFont, &ncma.lfSmCaptionFont);
|
|
pncmw->iMenuWidth = ncma.iMenuWidth;
|
|
pncmw->iMenuHeight = ncma.iMenuHeight;
|
|
LogFontWfromA(&pncmw->lfMenuFont, &ncma.lfMenuFont);
|
|
LogFontWfromA(&pncmw->lfStatusFont, &ncma.lfStatusFont);
|
|
LogFontWfromA(&pncmw->lfMessageFont, &ncma.lfMessageFont);
|
|
}
|
|
}
|
|
else
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
break;
|
|
}
|
|
|
|
case SPI_GETHIGHCONTRAST:
|
|
case SPI_SETHIGHCONTRAST:
|
|
{
|
|
LPHIGHCONTRASTW phc = (LPHIGHCONTRASTW)pvParam;
|
|
|
|
if(phc &&
|
|
((phc->cbSize == sizeof(HIGHCONTRASTW)) ||
|
|
(uiParam == sizeof(HIGHCONTRASTW))))
|
|
{
|
|
HIGHCONTRASTA hca;
|
|
|
|
ZeroMemory(&hca, sizeof(HIGHCONTRASTA));
|
|
hca.cbSize = sizeof(HIGHCONTRASTA);
|
|
|
|
if(uiAction == SPI_SETHIGHCONTRAST)
|
|
{
|
|
hca.dwFlags = phc->dwFlags;
|
|
GODOT_TO_ACP_STACKALLOC(phc->lpszDefaultScheme, hca.lpszDefaultScheme);
|
|
}
|
|
else
|
|
{
|
|
_STACKALLOC(LF_FULLFACESIZE, hca.lpszDefaultScheme);
|
|
}
|
|
|
|
if((hca.lpszDefaultScheme == NULL) &&
|
|
(phc->lpszDefaultScheme != NULL))
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
RetVal = SystemParametersInfoA(uiAction, sizeof(HIGHCONTRASTA), &hca, fWinIni);
|
|
|
|
if(RetVal &&
|
|
(uiAction == SPI_GETHIGHCONTRAST))
|
|
{
|
|
phc->cbSize = sizeof(HIGHCONTRASTW);
|
|
phc->dwFlags = hca.dwFlags;
|
|
if(FSTRING_VALID(hca.lpszDefaultScheme) &&
|
|
FSTRING_VALID(phc->lpszDefaultScheme))
|
|
{
|
|
MultiByteToWideChar(g_acp, 0, hca.lpszDefaultScheme, -1,
|
|
phc->lpszDefaultScheme, LF_FULLFACESIZE);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
break;
|
|
}
|
|
|
|
case SPI_GETICONMETRICS:
|
|
case SPI_SETICONMETRICS:
|
|
{
|
|
LPICONMETRICSW lpimw = (LPICONMETRICSW)pvParam;
|
|
|
|
if(lpimw &&
|
|
((lpimw->cbSize == sizeof(ICONMETRICSW)) ||
|
|
(uiParam == sizeof(ICONMETRICSW))))
|
|
{
|
|
ICONMETRICSA ima;
|
|
LPLOGFONTW lplfw = &lpimw->lfFont;
|
|
LPLOGFONTA lplfa = &ima.lfFont;
|
|
|
|
ZeroMemory(&ima, sizeof(ICONMETRICSA));
|
|
ima.cbSize = sizeof(ICONMETRICSA);
|
|
|
|
if(uiAction == SPI_SETICONMETRICS)
|
|
{
|
|
ima.iHorzSpacing = lpimw->iHorzSpacing;
|
|
ima.iVertSpacing = lpimw->iVertSpacing;
|
|
ima.iTitleWrap = lpimw->iTitleWrap;
|
|
LogFontAfromW(lplfa, lplfw);
|
|
}
|
|
|
|
RetVal = SystemParametersInfoA(uiAction, sizeof(ICONMETRICSA), &ima, fWinIni);
|
|
|
|
if(RetVal &&
|
|
(uiAction == SPI_GETICONMETRICS))
|
|
{
|
|
lpimw->cbSize = sizeof(ICONMETRICSW);
|
|
lpimw->iHorzSpacing = ima.iHorzSpacing;
|
|
lpimw->iVertSpacing = ima.iVertSpacing;
|
|
lpimw->iTitleWrap = ima.iTitleWrap;
|
|
LogFontWfromA(lplfw, lplfa);
|
|
}
|
|
}
|
|
else
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
break;
|
|
}
|
|
|
|
case SPI_GETICONTITLELOGFONT:
|
|
case SPI_SETICONTITLELOGFONT:
|
|
{
|
|
if (uiParam == sizeof(LOGFONTW))
|
|
{
|
|
LOGFONTA lfa;
|
|
LPLOGFONTW lplfw = (LPLOGFONTW)pvParam;
|
|
|
|
ZeroMemory(&lfa, sizeof(LOGFONTA));
|
|
|
|
if(uiAction == SPI_SETICONTITLELOGFONT)
|
|
LogFontAfromW(&lfa, lplfw);
|
|
|
|
RetVal = SystemParametersInfoA(uiAction, sizeof(LOGFONTA), &lfa, fWinIni);
|
|
|
|
if(RetVal && (uiAction == SPI_GETICONTITLELOGFONT))
|
|
LogFontWfromA(lplfw, &lfa);
|
|
}
|
|
else
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
break;
|
|
}
|
|
|
|
case SPI_GETSERIALKEYS:
|
|
case SPI_SETSERIALKEYS:
|
|
{
|
|
LPSERIALKEYSW lpskw = (LPSERIALKEYSW)pvParam;
|
|
|
|
if(lpskw &&
|
|
((lpskw->cbSize == sizeof(SERIALKEYSW)) ||
|
|
(uiParam == sizeof(SERIALKEYSW))))
|
|
{
|
|
SERIALKEYSA ska;
|
|
|
|
ZeroMemory(&ska, sizeof(SERIALKEYSA));
|
|
GODOT_TO_ACP_STACKALLOC(lpskw->lpszActivePort, ska.lpszActivePort);
|
|
if((ska.lpszActivePort == NULL) &&
|
|
(lpskw->lpszActivePort != NULL))
|
|
{
|
|
return(FALSE);
|
|
}
|
|
ska.lpszPort = NULL;
|
|
ska.cbSize = sizeof(SERIALKEYSA);
|
|
|
|
if(uiAction == SPI_SETSERIALKEYS)
|
|
{
|
|
ska.dwFlags = lpskw->dwFlags;
|
|
ska.iBaudRate = lpskw->iBaudRate;
|
|
ska.iPortState = lpskw->iPortState;
|
|
ska.iActive = lpskw->iActive;
|
|
}
|
|
|
|
RetVal = SystemParametersInfoA(uiAction, sizeof(SERIALKEYSA), &ska, fWinIni);
|
|
|
|
if(RetVal &&
|
|
(uiAction == SPI_GETSERIALKEYS))
|
|
{
|
|
lpskw->cbSize = sizeof(SERIALKEYSW);
|
|
lpskw->dwFlags = ska.dwFlags;
|
|
lpskw->iBaudRate = ska.iBaudRate;
|
|
lpskw->iPortState = ska.iPortState;
|
|
lpskw->iActive = ska.iActive;
|
|
}
|
|
}
|
|
else
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
break;
|
|
}
|
|
|
|
case SPI_GETSOUNDSENTRY:
|
|
case SPI_SETSOUNDSENTRY:
|
|
{
|
|
LPSOUNDSENTRYW lpssw = (LPSOUNDSENTRYW)pvParam;
|
|
|
|
if(lpssw &&
|
|
((lpssw->cbSize == sizeof(SOUNDSENTRYW)) ||
|
|
(uiParam == sizeof(SOUNDSENTRYW))))
|
|
{
|
|
SOUNDSENTRYA ssa;
|
|
|
|
ZeroMemory(&ssa, sizeof(SOUNDSENTRYA));
|
|
ssa.cbSize = sizeof(SOUNDSENTRYA);
|
|
|
|
if(uiAction == SPI_GETSOUNDSENTRY)
|
|
{
|
|
_STACKALLOC(MAX_PATH, ssa.lpszWindowsEffectDLL);
|
|
}
|
|
else // if(uiAction==SPI_SETSOUNDSENTRY)
|
|
{
|
|
ssa.dwFlags = lpssw->dwFlags;
|
|
ssa.iFSTextEffect = lpssw->iFSTextEffect;
|
|
ssa.iFSTextEffectMSec = lpssw->iFSTextEffectMSec;
|
|
ssa.iFSTextEffectColorBits = lpssw->iFSTextEffectColorBits;
|
|
ssa.iFSGrafEffect = lpssw->iFSGrafEffect;
|
|
ssa.iFSGrafEffectMSec = lpssw->iFSGrafEffectMSec;
|
|
ssa.iFSGrafEffectColor = lpssw->iFSGrafEffectColor;
|
|
ssa.iWindowsEffect = lpssw->iWindowsEffect;
|
|
ssa.iWindowsEffectMSec = lpssw->iWindowsEffectMSec;
|
|
GODOT_TO_ACP_STACKALLOC(lpssw->lpszWindowsEffectDLL, ssa.lpszWindowsEffectDLL);
|
|
ssa.iWindowsEffectOrdinal = lpssw->iWindowsEffectOrdinal;
|
|
}
|
|
|
|
if((ssa.lpszWindowsEffectDLL == NULL) &&
|
|
(lpssw->lpszWindowsEffectDLL != NULL))
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
RetVal = SystemParametersInfoA(uiAction, sizeof(SOUNDSENTRYA), &ssa, fWinIni);
|
|
|
|
if(RetVal &&
|
|
(uiAction == SPI_GETSOUNDSENTRY))
|
|
{
|
|
lpssw->cbSize = sizeof(SOUNDSENTRYW);
|
|
lpssw->dwFlags = ssa.dwFlags;
|
|
lpssw->iFSTextEffect = ssa.iFSTextEffect;
|
|
lpssw->iFSTextEffectMSec = ssa.iFSTextEffectMSec;
|
|
lpssw->iFSTextEffectColorBits = ssa.iFSTextEffectColorBits;
|
|
lpssw->iFSGrafEffect = ssa.iFSGrafEffect;
|
|
lpssw->iFSGrafEffectMSec = ssa.iFSGrafEffectMSec;
|
|
lpssw->iFSGrafEffectColor = ssa.iFSGrafEffectColor;
|
|
lpssw->iWindowsEffect = ssa.iWindowsEffect;
|
|
lpssw->iWindowsEffectMSec = ssa.iWindowsEffectMSec;
|
|
MultiByteToWideChar(g_acp, 0,
|
|
ssa.lpszWindowsEffectDLL, -1,
|
|
lpssw->lpszWindowsEffectDLL, MAX_PATH);
|
|
lpssw->iWindowsEffectOrdinal = ssa.iWindowsEffectOrdinal;
|
|
}
|
|
}
|
|
else
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
break;
|
|
}
|
|
|
|
case SPI_SETDESKWALLPAPER:
|
|
case SPI_GETDESKWALLPAPER:
|
|
{
|
|
LPSTR pvParamAnsi = NULL;
|
|
|
|
if(uiAction == SPI_SETDESKWALLPAPER)
|
|
GODOT_TO_ACP_STACKALLOC(pvParam, pvParamAnsi);
|
|
else
|
|
_STACKALLOC(MAX_PATH + 1, pvParamAnsi);
|
|
|
|
if((pvParamAnsi == NULL) &&
|
|
(pvParam != NULL))
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
RetVal = SystemParametersInfoA(uiAction, uiParam, pvParamAnsi, fWinIni);
|
|
|
|
if(RetVal &&
|
|
(uiAction == SPI_GETDESKWALLPAPER) &&
|
|
FSTRING_VALID(pvParamAnsi) &&
|
|
FSTRING_VALID((LPWSTR)pvParam))
|
|
{
|
|
MultiByteToWideChar(g_acp, 0, pvParamAnsi, -1, (LPWSTR)pvParam, MAX_PATH);
|
|
}
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
// Call the 'A' version of the API without conversion, etc.
|
|
RetVal = SystemParametersInfoA(uiAction, uiParam, pvParam, fWinIni);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=TranslateAcceleratorW
|
|
Begin=
|
|
int __stdcall
|
|
GodotTranslateAcceleratorW(HWND hWnd, HACCEL hAccTable, LPMSG lpMsg)
|
|
{
|
|
return((int)GodotDispatchMessage(mtTranslateAccelerator, hWnd, hAccTable, lpMsg));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=UpdateResourceW
|
|
Begin=
|
|
BOOL __stdcall GodotUpdateResourceW(HANDLE hUpdate, LPCWSTR lpType, LPCWSTR lpName,
|
|
WORD wLanguage, LPVOID lpData, DWORD cbData)
|
|
{
|
|
// UNSUPPORTED FUNCTION: Documented as a failure stub
|
|
return(UpdateResourceInternalW(hUpdate, lpType, lpName, wLanguage, lpData, cbData));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=VerFindFileW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotVerFindFileW( DWORD uFlags,
|
|
LPWSTR szFileName,
|
|
LPWSTR szWinDir,
|
|
LPWSTR szAppDir,
|
|
LPWSTR szCurDir,
|
|
PUINT lpuCurDirLen,
|
|
LPWSTR szDestDir,
|
|
PUINT lpuDestDirLen
|
|
)
|
|
{
|
|
// Begin locals
|
|
DWORD RetVal;
|
|
LPSTR szFileNameAnsi, szWinDirAnsi, szAppDirAnsi;
|
|
char szCurDirAnsi[MAX_PATH + 1];
|
|
char szDestDirAnsi[MAX_PATH + 1];
|
|
UINT uCurDirLen, uDestDirLen;
|
|
|
|
// Begin precall
|
|
GODOT_TO_ACP_STACKALLOC(szFileName, szFileNameAnsi);
|
|
GODOT_TO_ACP_STACKALLOC(szWinDir, szWinDirAnsi);
|
|
GODOT_TO_ACP_STACKALLOC(szAppDir, szAppDirAnsi);
|
|
if((!szFileNameAnsi && szFileName) ||
|
|
(!szWinDirAnsi && szWinDir) ||
|
|
(!szAppDirAnsi && szAppDir))
|
|
return(0);
|
|
|
|
uCurDirLen = *lpuCurDirLen * g_mcs;
|
|
uDestDirLen= *lpuDestDirLen * g_mcs;
|
|
ZeroMemory(szCurDirAnsi, MAX_PATH + 1);
|
|
ZeroMemory(szDestDirAnsi, MAX_PATH + 1);
|
|
|
|
RetVal=VerFindFileA(uFlags, szFileNameAnsi, szWinDirAnsi, szAppDirAnsi, szCurDirAnsi,
|
|
&uCurDirLen, szDestDirAnsi, &uDestDirLen);
|
|
|
|
// Begin postcall: note that we do not care what the return value
|
|
// really was,since these buffer sizes are set either way.
|
|
if(uCurDirLen > *lpuCurDirLen)
|
|
*lpuCurDirLen = uCurDirLen;
|
|
else
|
|
{
|
|
MultiByteToWideChar(g_acp, 0, szCurDirAnsi, -1, szCurDir, *lpuCurDirLen);
|
|
*lpuCurDirLen = gwcslen(szCurDir);
|
|
}
|
|
|
|
if(uDestDirLen > *lpuDestDirLen)
|
|
*lpuDestDirLen = uCurDirLen;
|
|
else
|
|
{
|
|
// Convert the full length of the ANSI name into the full size of the Unicode buffer
|
|
MultiByteToWideChar(g_acp, 0, szDestDirAnsi, -1, szDestDir, *lpuDestDirLen);
|
|
*lpuDestDirLen = gwcslen(szDestDir);
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=VerInstallFileW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotVerInstallFileW( DWORD uFlags,
|
|
LPWSTR szSrcFileName,
|
|
LPWSTR szDestFileName,
|
|
LPWSTR szSrcDir,
|
|
LPWSTR szDestDir,
|
|
LPWSTR szCurDir,
|
|
LPWSTR szTmpFile,
|
|
PUINT lpuTmpFileLen
|
|
)
|
|
{
|
|
// Begin locals
|
|
DWORD RetVal;
|
|
LPSTR szSrcFileNameAnsi, szDestFileNameAnsi, szSrcDirAnsi, szDestDirAnsi, szCurDirAnsi;
|
|
CHAR szTmpFileAnsi[MAX_PATH + 1];
|
|
UINT uTmpFileLen;
|
|
|
|
// Begin precall
|
|
GODOT_TO_ACP_STACKALLOC(szSrcFileName, szSrcFileNameAnsi);
|
|
GODOT_TO_ACP_STACKALLOC(szDestFileName, szDestFileNameAnsi);
|
|
GODOT_TO_ACP_STACKALLOC(szSrcDir, szSrcDirAnsi);
|
|
GODOT_TO_ACP_STACKALLOC(szDestDir, szDestDirAnsi);
|
|
GODOT_TO_ACP_STACKALLOC(szCurDir, szCurDirAnsi);
|
|
if((!szSrcFileNameAnsi && szSrcFileName) ||
|
|
(!szDestFileNameAnsi && szDestFileName) ||
|
|
(!szSrcDirAnsi && szSrcDir) ||
|
|
(!szDestDirAnsi && szDestDir) ||
|
|
(!szCurDirAnsi && szCurDir))
|
|
return(0);
|
|
|
|
uTmpFileLen = *lpuTmpFileLen * g_mcs;
|
|
ZeroMemory(&szTmpFileAnsi, MAX_PATH + 1);
|
|
|
|
RetVal=VerInstallFileA(uFlags, szSrcFileNameAnsi, szDestFileNameAnsi, szSrcDirAnsi,
|
|
szDestDirAnsi, szCurDirAnsi, szTmpFileAnsi, &uTmpFileLen);
|
|
|
|
// Begin postcall: note that we do not care what the return value
|
|
// really was,since these buffer sizes must be set either way.
|
|
if(uTmpFileLen > *lpuTmpFileLen)
|
|
*lpuTmpFileLen = uTmpFileLen;
|
|
else
|
|
{
|
|
// Convert the full length of the ANSI name into the full size of the Unicode buffer
|
|
MultiByteToWideChar(g_acp, 0, szTmpFileAnsi, -1, szTmpFile, *lpuTmpFileLen);
|
|
*lpuTmpFileLen = gwcslen(szTmpFile);
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=VerLanguageNameW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotVerLanguageNameW(DWORD wLang, LPWSTR szLang, DWORD nSize)
|
|
{
|
|
DWORD RetVal;
|
|
LPSTR szLangAnsi = NULL;
|
|
|
|
_STACKALLOC((nSize *g_mcs) + 1, szLangAnsi);
|
|
if(szLangAnsi==NULL)
|
|
{
|
|
return(0);
|
|
}
|
|
ZeroMemory(szLangAnsi, (nSize * g_mcs) + 1);
|
|
|
|
RetVal=VerLanguageNameA(wLang, szLangAnsi, nSize);
|
|
|
|
// kinda sucks but we are not being any worse than
|
|
// the OS is here -- See Windows Bugs # 311758 for
|
|
// more details
|
|
if(szLang)
|
|
{
|
|
if (RetVal < nSize)
|
|
MultiByteToWideChar(g_acp, 0, szLangAnsi, -1, szLang, RetVal);
|
|
else
|
|
MultiByteToWideChar(g_acp, 0, szLangAnsi, -1, szLang, nSize);
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=VerQueryValueW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotVerQueryValueW(const LPVOID pBlock, LPWSTR lpSubBlock, LPVOID * lplpBuffer, PUINT puLen)
|
|
{
|
|
const WCHAR pwzStringFileInfo[] = L"\\StringFileInfo";
|
|
|
|
BOOL RetVal;
|
|
LPSTR lpSubBlockAnsi;
|
|
BYTE* pbyt;
|
|
LPWSTR lpwz;
|
|
|
|
// Begin precall
|
|
GODOT_TO_ACP_STACKALLOC(lpSubBlock, lpSubBlockAnsi);
|
|
if(lpSubBlockAnsi==NULL)
|
|
{
|
|
return(FALSE);
|
|
}
|
|
pbyt = (BYTE*)pBlock + VERINFO_BUFFER;
|
|
|
|
RetVal=VerQueryValueA((void *)pbyt, lpSubBlockAnsi, lplpBuffer, puLen);
|
|
|
|
if (RetVal && (gwcsncmp(pwzStringFileInfo, lpSubBlock, gwcslen(pwzStringFileInfo)) == 0))
|
|
{
|
|
// Ok, this means we have to convert. We have a string. :-)
|
|
lpwz = (LPWSTR)pBlock;
|
|
if (*puLen == 0)
|
|
lpwz = L'\0';
|
|
else
|
|
MultiByteToWideChar(g_acp, 0, *lplpBuffer, -1, lpwz, VERINFO_BUFFER/sizeof(WCHAR));
|
|
|
|
if(lplpBuffer)
|
|
*lplpBuffer = lpwz;
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=VkKeyScanW
|
|
Begin=
|
|
SHORT __stdcall
|
|
GodotVkKeyScanW(WCHAR ch)
|
|
{
|
|
char chAnsi;
|
|
UINT cpg = CpgFromLocale(LOWORD(GetKeyboardLayout(0)));
|
|
UINT mcs = CbPerChOfCpg(cpg);
|
|
|
|
WideCharToMultiByte(cpg, 0, (WCHAR *)&ch, 1, (CHAR *)&chAnsi, sizeof(char), NULL, NULL);
|
|
|
|
return(VkKeyScanA(chAnsi));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=VkKeyScanExW
|
|
Begin=
|
|
SHORT __stdcall
|
|
GodotVkKeyScanExW(WCHAR ch, HKL dwhkl)
|
|
{
|
|
char chAnsi;
|
|
UINT cpg = CpgFromLocale(LOWORD(dwhkl));
|
|
UINT mcs = CbPerChOfCpg(cpg);
|
|
|
|
WideCharToMultiByte(cpg, 0, (WCHAR *)&ch, 1, (CHAR *)&chAnsi, sizeof(char), NULL, NULL);
|
|
|
|
return(VkKeyScanExA(chAnsi, dwhkl));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=waveInGetDevCapsW
|
|
Begin=
|
|
MMRESULT __stdcall GodotwaveInGetDevCapsW(UINT_PTR uDeviceID, LPWAVEINCAPSW pwic, UINT cbwic)
|
|
{
|
|
// UNSUPPORTED FUNCTION: Documented as a failure stub
|
|
|
|
if(cbwic < sizeof(WAVEINCAPSW))
|
|
{
|
|
return(MMSYSERR_INVALPARAM);
|
|
}
|
|
else
|
|
{
|
|
WAVEINCAPSA wicA;
|
|
MMRESULT RetVal;
|
|
|
|
ZeroMemory(&wicA, sizeof(WAVEINCAPSA));
|
|
RetVal = waveInGetDevCapsA(uDeviceID, &wicA, sizeof(WAVEINCAPSA));
|
|
|
|
if(RetVal == MMSYSERR_NOERROR)
|
|
{
|
|
pwic->wMid = wicA.wMid;
|
|
pwic->wPid = wicA.wPid;
|
|
pwic->vDriverVersion = wicA.vDriverVersion;
|
|
pwic->dwFormats = wicA.dwFormats;
|
|
pwic->wChannels = wicA.wChannels;
|
|
pwic->wReserved1 = wicA.wReserved1;
|
|
MultiByteToWideChar(g_acp, 0, wicA.szPname, MAXPNAMELEN, pwic->szPname, MAXPNAMELEN);
|
|
}
|
|
return(RetVal);
|
|
}
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=waveInGetErrorTextW
|
|
Begin=
|
|
MMRESULT __stdcall GodotwaveInGetErrorTextW(MMRESULT mmrError, LPWSTR pszText, UINT cchText)
|
|
{
|
|
// UNSUPPORTED FUNCTION: Documented as a failure stub
|
|
|
|
if(pszText==NULL || cchText == 0)
|
|
return(waveInGetErrorTextA(mmrError, (LPSTR)pszText, cchText));
|
|
else
|
|
{
|
|
LPSTR pszTextA;
|
|
MMRESULT RetVal;
|
|
|
|
_STACKALLOC((cchText * g_mcs) + 1, pszTextA);
|
|
if(!pszTextA)
|
|
return(MMSYSERR_NOMEM);
|
|
ZeroMemory(pszTextA, (cchText * g_mcs) + 1);
|
|
|
|
RetVal = waveInGetErrorTextA(mmrError, pszTextA, cchText);
|
|
|
|
if(RetVal == MMSYSERR_NOERROR)
|
|
MultiByteToWideChar(g_acp, 0, pszTextA, -1, pszText, cchText);
|
|
|
|
return(RetVal);
|
|
}
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=waveOutGetDevCapsW
|
|
Begin=
|
|
MMRESULT __stdcall GodotwaveOutGetDevCapsW(UINT_PTR uDeviceID, LPWAVEOUTCAPSW pwoc, UINT cbwoc)
|
|
{
|
|
// UNSUPPORTED FUNCTION: Documented as a failure stub
|
|
|
|
if(cbwoc < sizeof(WAVEOUTCAPSW))
|
|
{
|
|
return(MMSYSERR_INVALPARAM);
|
|
}
|
|
else
|
|
{
|
|
WAVEOUTCAPSA wocA;
|
|
MMRESULT RetVal;
|
|
|
|
ZeroMemory(&wocA, sizeof(WAVEOUTCAPS));
|
|
RetVal = waveOutGetDevCapsA(uDeviceID, &wocA, sizeof(WAVEOUTCAPSA));
|
|
|
|
if(RetVal == MMSYSERR_NOERROR)
|
|
{
|
|
pwoc->wMid = wocA.wMid;
|
|
pwoc->wPid = wocA.wPid;
|
|
pwoc->vDriverVersion = wocA.vDriverVersion;
|
|
pwoc->dwFormats = wocA.dwFormats;
|
|
pwoc->wChannels = wocA.wChannels;
|
|
pwoc->wReserved1 = wocA.wReserved1;
|
|
pwoc->dwSupport = wocA.dwSupport;
|
|
MultiByteToWideChar(g_acp, 0, wocA.szPname, MAXPNAMELEN, pwoc->szPname, MAXPNAMELEN);
|
|
}
|
|
return(RetVal);
|
|
}
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=waveOutGetErrorTextW
|
|
Begin=
|
|
MMRESULT __stdcall GodotwaveOutGetErrorTextW(MMRESULT mmrError, LPWSTR pszText, UINT cchText)
|
|
{
|
|
// UNSUPPORTED FUNCTION: Documented as a failure stub
|
|
|
|
if(pszText==NULL || cchText == 0)
|
|
return(waveOutGetErrorTextA(mmrError, (LPSTR)pszText, cchText));
|
|
else
|
|
{
|
|
LPSTR pszTextA;
|
|
MMRESULT RetVal;
|
|
|
|
_STACKALLOC((cchText * g_mcs) + 1, pszTextA);
|
|
if(!pszTextA)
|
|
return(MMSYSERR_NOMEM);
|
|
ZeroMemory(pszTextA, (cchText * g_mcs) + 1);
|
|
|
|
RetVal = waveOutGetErrorTextA(mmrError, pszTextA, cchText);
|
|
|
|
if(RetVal == MMSYSERR_NOERROR)
|
|
MultiByteToWideChar(g_acp, 0, pszTextA, -1, pszText, cchText);
|
|
|
|
return(RetVal);
|
|
}
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=WideCharToMultiByte
|
|
Begin=
|
|
// WideCharToMultiByte is wrapped for UTF-7/UTF-8 support
|
|
int __stdcall
|
|
GodotWideCharToMultiByte( UINT CodePage,
|
|
DWORD dwFlags,
|
|
LPCWSTR lpWideCharStr,
|
|
int cchWideChar,
|
|
LPSTR lpMultiByteStr,
|
|
int cbMultiByte,
|
|
LPCSTR lpDefaultChar,
|
|
LPBOOL lpUsedDefaultChar
|
|
)
|
|
{
|
|
UINT cpg = ((CodePage == CP_THREAD_ACP) ? g_acp : CodePage);
|
|
|
|
// See if it's a special code page value for UTF translations.
|
|
if (cpg >= NLS_CP_ALGORITHM_RANGE)
|
|
return(UnicodeToUTF(cpg, dwFlags, lpWideCharStr, cchWideChar,
|
|
lpMultiByteStr, cbMultiByte, lpDefaultChar, lpUsedDefaultChar));
|
|
|
|
// GB 18030 specified?
|
|
if (cpg == CP_GB18030)
|
|
return(GB18030Helper(cpg,
|
|
dwFlags | NLS_CP_WCTOMB,
|
|
lpMultiByteStr,
|
|
cbMultiByte,
|
|
(LPWSTR)lpWideCharStr,
|
|
cchWideChar,
|
|
NULL));
|
|
|
|
return(WideCharToMultiByte(cpg, dwFlags, lpWideCharStr, cchWideChar,
|
|
lpMultiByteStr, cbMultiByte, lpDefaultChar, lpUsedDefaultChar));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=WinHelpW
|
|
Begin=
|
|
BOOL __stdcall
|
|
GodotWinHelpW(HWND hWndMain, LPCWSTR lpszHelp, UINT uCommand, ULONG_PTR dwData)
|
|
{
|
|
LPSTR lpszHelpAnsi;
|
|
|
|
GODOT_TO_ACP_STACKALLOC(lpszHelp, lpszHelpAnsi);
|
|
|
|
switch(uCommand & ~HELP_TCARD)
|
|
{
|
|
case HELP_COMMAND:
|
|
case HELP_KEY:
|
|
case HELP_PARTIALKEY:
|
|
{
|
|
ULONG_PTR dwDataAnsi;
|
|
GODOT_TO_ACP_STACKALLOC(dwData, dwDataAnsi);
|
|
return(WinHelpA(hWndMain, lpszHelpAnsi, uCommand, dwData));
|
|
break;
|
|
}
|
|
|
|
case HELP_MULTIKEY:
|
|
{
|
|
LPMULTIKEYHELPW lpmkh = (LPMULTIKEYHELPW)dwData;
|
|
MULTIKEYHELPA mkhA;
|
|
char * szKeyPhrase;
|
|
size_t cchKeyPhrase;
|
|
|
|
ZeroMemory(&mkhA, sizeof(MULTIKEYHELPA));
|
|
mkhA.mkSize = sizeof(MULTIKEYHELPA);
|
|
WideCharToMultiByte(g_acp, 0,
|
|
(WCHAR *)&(lpmkh->mkKeylist), 1,
|
|
(CHAR *)&(mkhA.mkKeylist), sizeof(char),
|
|
NULL, NULL);
|
|
cchKeyPhrase = gwcslen(lpmkh->szKeyphrase) + 1;
|
|
_STACKALLOC(cchKeyPhrase*g_mcs, szKeyPhrase);
|
|
WideCharToMultiByte(g_acp, 0,
|
|
lpmkh->szKeyphrase, cchKeyPhrase,
|
|
szKeyPhrase, cchKeyPhrase*g_mcs,
|
|
NULL, NULL);
|
|
lstrcpyA(mkhA.szKeyphrase, szKeyPhrase);
|
|
|
|
return(WinHelpA(hWndMain, lpszHelpAnsi, uCommand, (ULONG_PTR)&mkhA));
|
|
break;
|
|
}
|
|
|
|
case HELP_SETWINPOS:
|
|
{
|
|
LPHELPWININFOW lphwi = (LPHELPWININFOW)dwData;
|
|
LPHELPWININFOA lphwiA;
|
|
LPSTR lpAnsiKey;
|
|
size_t cchMember;
|
|
BOOL RetVal;
|
|
|
|
lphwiA = LocalAlloc(LPTR, (lphwi->wStructSize));
|
|
if(!lphwiA)
|
|
return(FALSE);
|
|
else
|
|
{
|
|
*lphwiA = *((LPHELPWININFOA)dwData); // copies identical parts
|
|
lphwiA->wStructSize = sizeof(HELPWININFOA);
|
|
cchMember = gwcslen(lphwi->rgchMember) + 1;
|
|
_STACKALLOC(cchMember*g_mcs, lpAnsiKey);
|
|
WideCharToMultiByte(g_acp,
|
|
0,
|
|
lphwi->rgchMember,
|
|
cchMember,
|
|
lpAnsiKey,
|
|
cchMember*g_mcs,
|
|
NULL,
|
|
NULL);
|
|
lstrcpyA(lphwiA->rgchMember, lpAnsiKey);
|
|
|
|
RetVal = WinHelpA(hWndMain, lpszHelpAnsi, uCommand, (ULONG_PTR)lphwiA);
|
|
LocalFree(lphwiA);
|
|
return(RetVal);
|
|
}
|
|
break;
|
|
}
|
|
|
|
default:
|
|
return(WinHelpA(hWndMain, lpszHelpAnsi, uCommand, dwData));
|
|
break;
|
|
}
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=WNetAddConnection2W
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotWNetAddConnection2W(LPNETRESOURCEW lpnrw, LPCWSTR lpPassword, LPCWSTR lpUserName, DWORD dwFlags)
|
|
{
|
|
// Begin locals
|
|
LPSTR lpPasswordAnsi;
|
|
LPSTR lpUserNameAnsi;
|
|
NETRESOURCEA nra;
|
|
|
|
// Begin precall
|
|
ZeroMemory(&nra, sizeof(NETRESOURCEA));
|
|
memcpy(&nra, lpnrw, (4*sizeof(DWORD)));
|
|
GODOT_TO_ACP_STACKALLOC(lpnrw->lpLocalName, nra.lpLocalName);
|
|
GODOT_TO_ACP_STACKALLOC(lpnrw->lpRemoteName, nra.lpRemoteName);
|
|
GODOT_TO_ACP_STACKALLOC(lpnrw->lpComment, nra.lpComment);
|
|
GODOT_TO_ACP_STACKALLOC(lpnrw->lpProvider, nra.lpProvider);
|
|
GODOT_TO_ACP_STACKALLOC(lpUserName, lpUserNameAnsi);
|
|
GODOT_TO_ACP_STACKALLOC(lpPassword, lpPasswordAnsi);
|
|
if((!nra.lpLocalName && lpnrw->lpLocalName) ||
|
|
(!nra.lpLocalName && lpnrw->lpLocalName) ||
|
|
(!nra.lpLocalName && lpnrw->lpLocalName) ||
|
|
(!nra.lpLocalName && lpnrw->lpLocalName) ||
|
|
(!lpUserNameAnsi && lpUserName) ||
|
|
(!lpPasswordAnsi && lpPassword))
|
|
{
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(ERROR_EXTENDED_ERROR);
|
|
}
|
|
|
|
return(WNetAddConnection2A(&nra, lpPasswordAnsi, lpUserNameAnsi, dwFlags));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=WNetAddConnection3W
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotWNetAddConnection3W(HWND hwnd, LPNETRESOURCEW lpnrw, LPCWSTR lpPassword, LPCWSTR lpUser, DWORD dwFlags)
|
|
{
|
|
// Begin locals
|
|
LPSTR lpPasswordAnsi;
|
|
LPSTR lpUserNameAnsi;
|
|
NETRESOURCEA nra;
|
|
|
|
// Begin precall
|
|
ZeroMemory(&nra, sizeof(NETRESOURCEA));
|
|
memcpy(&nra, lpnrw, (4*sizeof(DWORD)));
|
|
GODOT_TO_ACP_STACKALLOC(lpnrw->lpLocalName, nra.lpLocalName);
|
|
GODOT_TO_ACP_STACKALLOC(lpnrw->lpRemoteName, nra.lpRemoteName);
|
|
GODOT_TO_ACP_STACKALLOC(lpnrw->lpComment, nra.lpComment);
|
|
GODOT_TO_ACP_STACKALLOC(lpnrw->lpProvider, nra.lpProvider);
|
|
GODOT_TO_ACP_STACKALLOC(lpUser, lpUserNameAnsi);
|
|
GODOT_TO_ACP_STACKALLOC(lpPassword, lpPasswordAnsi);
|
|
if((!nra.lpLocalName && lpnrw->lpLocalName) ||
|
|
(!nra.lpLocalName && lpnrw->lpLocalName) ||
|
|
(!nra.lpLocalName && lpnrw->lpLocalName) ||
|
|
(!nra.lpLocalName && lpnrw->lpLocalName) ||
|
|
(!lpUserNameAnsi && lpUser) ||
|
|
(!lpPasswordAnsi && lpPassword))
|
|
{
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(ERROR_EXTENDED_ERROR);
|
|
}
|
|
|
|
return(WNetAddConnection3A(hwnd, &nra, lpPasswordAnsi, lpUserNameAnsi, dwFlags));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=WNetConnectionDialog1W
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotWNetConnectionDialog1W(LPCONNECTDLGSTRUCTW lpConnDlgStruct)
|
|
{
|
|
// Begin locals
|
|
CONNECTDLGSTRUCTA cdsa;
|
|
|
|
// Begin precall
|
|
ZeroMemory(&cdsa, sizeof(CONNECTDLGSTRUCTA));
|
|
cdsa.cbStructure = lpConnDlgStruct->cbStructure;
|
|
cdsa.hwndOwner = lpConnDlgStruct->hwndOwner;
|
|
memcpy(&(cdsa.lpConnRes), lpConnDlgStruct->lpConnRes, (4*sizeof(DWORD)));
|
|
GODOT_TO_ACP_STACKALLOC((lpConnDlgStruct->lpConnRes)->lpLocalName, (cdsa.lpConnRes)->lpLocalName);
|
|
GODOT_TO_ACP_STACKALLOC((lpConnDlgStruct->lpConnRes)->lpRemoteName, (cdsa.lpConnRes)->lpRemoteName);
|
|
GODOT_TO_ACP_STACKALLOC((lpConnDlgStruct->lpConnRes)->lpComment, (cdsa.lpConnRes)->lpComment);
|
|
GODOT_TO_ACP_STACKALLOC((lpConnDlgStruct->lpConnRes)->lpProvider, (cdsa.lpConnRes)->lpProvider);
|
|
if((!(cdsa.lpConnRes)->lpLocalName && (lpConnDlgStruct->lpConnRes)->lpLocalName) ||
|
|
(!(cdsa.lpConnRes)->lpRemoteName && (lpConnDlgStruct->lpConnRes)->lpRemoteName) ||
|
|
(!(cdsa.lpConnRes)->lpComment && (lpConnDlgStruct->lpConnRes)->lpComment) ||
|
|
(!(cdsa.lpConnRes)->lpProvider && (lpConnDlgStruct->lpConnRes)->lpProvider))
|
|
{
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(ERROR_EXTENDED_ERROR);
|
|
}
|
|
cdsa.dwFlags = lpConnDlgStruct->dwFlags;
|
|
cdsa.dwDevNum = lpConnDlgStruct->dwDevNum;
|
|
|
|
// Call the 'A' version of the API
|
|
return(WNetConnectionDialog1A(&cdsa));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=WNetDisconnectDialog1W
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotWNetDisconnectDialog1W(LPDISCDLGSTRUCTW lpConnDlgStruct)
|
|
{
|
|
// Begin locals
|
|
DISCDLGSTRUCTA ddsa;
|
|
|
|
// Begin precall
|
|
ZeroMemory(&ddsa, sizeof(DISCDLGSTRUCTA));
|
|
ddsa.cbStructure = lpConnDlgStruct->cbStructure;
|
|
ddsa.hwndOwner = lpConnDlgStruct->hwndOwner;
|
|
ddsa.dwFlags = lpConnDlgStruct->dwFlags;
|
|
GODOT_TO_ACP_STACKALLOC(lpConnDlgStruct->lpLocalName, ddsa.lpLocalName);
|
|
GODOT_TO_ACP_STACKALLOC(lpConnDlgStruct->lpRemoteName, ddsa.lpRemoteName);
|
|
if((!ddsa.lpLocalName && lpConnDlgStruct->lpLocalName) ||
|
|
(!ddsa.lpRemoteName && lpConnDlgStruct->lpRemoteName))
|
|
{
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(ERROR_EXTENDED_ERROR);
|
|
}
|
|
|
|
// Call the 'A' version of the API
|
|
return(WNetDisconnectDialog1A(&ddsa));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=WNetGetConnectionW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotWNetGetConnectionW(LPCWSTR lpLocalName, LPWSTR lpRemoteName, LPDWORD lpnLength)
|
|
{
|
|
// Begin locals
|
|
DWORD RetVal;
|
|
LPSTR lpLocalNameAnsi;
|
|
LPSTR lpRemoteNameAnsi;
|
|
DWORD nLength;
|
|
|
|
// Begin precall
|
|
GODOT_TO_ACP_STACKALLOC(lpLocalName, lpLocalNameAnsi);
|
|
|
|
if(!lpnLength)
|
|
nLength = 0;
|
|
else
|
|
nLength = (*lpnLength * g_mcs) + 1;
|
|
_STACKALLOC(nLength, lpRemoteNameAnsi);
|
|
|
|
RetVal=WNetGetConnectionA(lpLocalNameAnsi, lpRemoteNameAnsi, &nLength);
|
|
|
|
if(RetVal==NO_ERROR)
|
|
{
|
|
if(lpnLength)
|
|
{
|
|
MultiByteToWideChar(g_acp, 0, lpRemoteNameAnsi, nLength, lpRemoteName, *lpnLength);
|
|
*lpnLength = gwcslen(lpRemoteName);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(lpnLength)
|
|
*lpnLength = nLength;
|
|
}
|
|
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=WNetGetLastErrorW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotWNetGetLastErrorW(LPDWORD lpError, LPWSTR lpszError, DWORD cchError, LPWSTR lpszName, DWORD cchName)
|
|
{
|
|
DWORD RetVal;
|
|
LPSTR lpErrorBufAnsi;
|
|
LPSTR lpNameBufAnsi;
|
|
|
|
// Begin precall
|
|
_STACKALLOC((cchError*g_mcs)+1, lpErrorBufAnsi);
|
|
_STACKALLOC((cchName*g_mcs)+1, lpNameBufAnsi);
|
|
if((lpErrorBufAnsi==NULL) || (lpNameBufAnsi==NULL))
|
|
{
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(0);
|
|
}
|
|
ZeroMemory(lpErrorBufAnsi, (cchError*g_mcs)+1);
|
|
ZeroMemory(lpNameBufAnsi, (cchName*g_mcs)+1);
|
|
|
|
RetVal=WNetGetLastErrorA(lpError, lpErrorBufAnsi, cchError, lpNameBufAnsi, cchName);
|
|
|
|
if(RetVal==NO_ERROR)
|
|
{
|
|
MultiByteToWideChar(g_acp, 0, lpErrorBufAnsi, -1, lpszError, cchError);
|
|
MultiByteToWideChar(g_acp, 0, lpNameBufAnsi, -1, lpszName, cchName);
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=WNetGetProviderNameW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotWNetGetProviderNameW(DWORD dwNetType, LPWSTR lpProviderName, LPDWORD lpBufferSize)
|
|
{
|
|
// Begin locals
|
|
DWORD RetVal;
|
|
LPSTR lpProviderNameAnsi;
|
|
|
|
// Note that the PSDK docs that the buffer must be at least
|
|
// one character.
|
|
if((!lpProviderName) || (!lpBufferSize) || (!(*lpBufferSize)))
|
|
RetVal = ERROR_INVALID_ADDRESS;
|
|
else
|
|
{
|
|
_STACKALLOC((*lpBufferSize + 1)*g_mcs, lpProviderNameAnsi);
|
|
|
|
// Call the 'A' version of the API
|
|
RetVal=WNetGetProviderNameA(dwNetType, lpProviderNameAnsi, lpBufferSize);
|
|
|
|
// Begin postcall
|
|
if(RetVal==NO_ERROR)
|
|
{
|
|
MultiByteToWideChar(g_acp, 0, lpProviderNameAnsi, -1, lpProviderName, *lpBufferSize);
|
|
}
|
|
else if(RetVal == ERROR_MORE_DATA)
|
|
{
|
|
// We do not know the exact size here, so out best guess is the
|
|
// size of the string. Note that we are getting back bytes here
|
|
// but need to pass back characters. This means we will divide by
|
|
// two on DBCS.
|
|
*lpBufferSize = (*lpBufferSize / g_mcs);
|
|
}
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=WNetGetResourceInformationW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotWNetGetResourceInformationW(LPNETRESOURCEW lpnrw, LPVOID lpBuffer, LPDWORD lpcb, LPWSTR * lplpSystem)
|
|
{
|
|
// Begin locals
|
|
DWORD RetVal;
|
|
NETRESOURCEA nra;
|
|
LPSTR * lplpSystemAnsi = NULL;
|
|
LPVOID lpBufferAnsi;
|
|
LPNETRESOURCEW lprnw;
|
|
LPNETRESOURCEA lpnraOut;
|
|
DWORD dwOffset;
|
|
LPWSTR lpwz;
|
|
size_t cbSystem;
|
|
|
|
ZeroMemory(&nra, sizeof(NETRESOURCEA));
|
|
memcpy(&nra, lpnrw, (4*sizeof(DWORD)));
|
|
GODOT_TO_ACP_STACKALLOC(lpnrw->lpLocalName, nra.lpLocalName);
|
|
GODOT_TO_ACP_STACKALLOC(lpnrw->lpRemoteName, nra.lpRemoteName);
|
|
GODOT_TO_ACP_STACKALLOC(lpnrw->lpComment, nra.lpComment);
|
|
GODOT_TO_ACP_STACKALLOC(lpnrw->lpProvider, nra.lpProvider);
|
|
if((!nra.lpLocalName && lpnrw->lpLocalName) ||
|
|
(!nra.lpLocalName && lpnrw->lpLocalName) ||
|
|
(!nra.lpLocalName && lpnrw->lpLocalName) ||
|
|
(!nra.lpLocalName && lpnrw->lpLocalName))
|
|
{
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(ERROR_EXTENDED_ERROR);
|
|
}
|
|
|
|
// Set up the buffer if there is one, otherwise
|
|
// pass NULLL to try to get a buffer size
|
|
if(lpcb && *lpcb)
|
|
{
|
|
_STACKALLOC(*lpcb, lpBufferAnsi);
|
|
}
|
|
else
|
|
lpBufferAnsi = NULL;
|
|
|
|
// Call the 'A' version of the API
|
|
RetVal=WNetGetResourceInformationA(&nra, lpBuffer, lpcb, lplpSystemAnsi);
|
|
|
|
// Begin postcall
|
|
if(RetVal==NO_ERROR)
|
|
{
|
|
// Set up our NETRESOURCE vars
|
|
lpnraOut = lpBufferAnsi;
|
|
lprnw = lpBuffer;
|
|
|
|
// Copy the first four (non-string) parameters and set the offset
|
|
memcpy(lpnrw, lpnraOut, (4*sizeof(DWORD)));
|
|
dwOffset = sizeof(NETRESOURCEW);
|
|
|
|
// Local name
|
|
lpwz = (LPWSTR)&lprnw + dwOffset;
|
|
MultiByteToWideChar(g_acp, 0, lpnraOut->lpLocalName, -1, lpwz, -1);
|
|
dwOffset += (lpwz ? gwcslen(lpwz) + 1 : 0);
|
|
lpnrw->lpLocalName = lpwz;
|
|
|
|
// Remote name
|
|
lpwz = (LPWSTR)&lprnw + dwOffset;
|
|
MultiByteToWideChar(g_acp, 0, lpnraOut->lpRemoteName, -1, lpwz, -1);
|
|
dwOffset += (lpwz ? gwcslen(lpwz) + 1 : 0);
|
|
lpnrw->lpRemoteName = lpwz;
|
|
|
|
// Comment
|
|
lpwz = (LPWSTR)&lprnw + dwOffset;
|
|
MultiByteToWideChar(g_acp, 0, lpnraOut->lpComment, -1, lpwz, -1);
|
|
dwOffset += (lpwz ? gwcslen(lpwz) + 1 : 0);
|
|
lpnrw->lpComment = lpwz;
|
|
|
|
// Provider
|
|
lpwz = (LPWSTR)&lprnw + dwOffset;
|
|
MultiByteToWideChar(g_acp, 0, lpnraOut->lpProvider, -1, lpwz, -1);
|
|
dwOffset += (lpwz ? gwcslen(lpwz) + 1 : 0);
|
|
lpnrw->lpProvider = lpwz;
|
|
|
|
if(lplpSystem && lplpSystemAnsi)
|
|
{
|
|
// Now we take care of lplpSystemAnsi. We cannot directly do this, but we
|
|
// can convert it to a temp buffer, search for the string in the caller's
|
|
// lpBuffer with gwcsstr and let it return that pointer if there is one.
|
|
cbSystem = strlen(*lplpSystemAnsi);
|
|
_STACKALLOC((cbSystem * g_mcs) + 1, lpwz);
|
|
MultiByteToWideChar(g_acp, 0, *lplpSystemAnsi, -1, lpwz, cbSystem);
|
|
*lplpSystem = gwcsstr(lpBuffer, lpwz);
|
|
}
|
|
}
|
|
else if (RetVal==ERROR_MORE_DATA && lpcb)
|
|
{
|
|
// We do not know the exact size here, so out best guess is the
|
|
// size of the "A" buffer we get back, *2 for all of the structure
|
|
// past the NETRESOURCEA part.
|
|
*lpcb = (sizeof(NETRESOURCEA) +
|
|
((*lpcb - (sizeof(NETRESOURCEA))) * sizeof(WCHAR)));
|
|
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=WNetGetResourceParentW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotWNetGetResourceParentW(LPNETRESOURCEW lpnrw, LPVOID lpBuffer, LPDWORD lpcbBuffer)
|
|
{
|
|
// Begin locals
|
|
DWORD RetVal;
|
|
NETRESOURCEA nra;
|
|
LPVOID lpBufferAnsi;
|
|
LPNETRESOURCEW lprnw;
|
|
LPNETRESOURCEA lpnraOut;
|
|
DWORD dwOffset;
|
|
LPWSTR lpwz;
|
|
|
|
// Begin precall
|
|
ZeroMemory(&nra, sizeof(NETRESOURCEA));
|
|
memcpy(&nra, lpnrw, (4*sizeof(DWORD)));
|
|
GODOT_TO_ACP_STACKALLOC(lpnrw->lpLocalName, nra.lpLocalName);
|
|
GODOT_TO_ACP_STACKALLOC(lpnrw->lpRemoteName, nra.lpRemoteName);
|
|
GODOT_TO_ACP_STACKALLOC(lpnrw->lpComment, nra.lpComment);
|
|
GODOT_TO_ACP_STACKALLOC(lpnrw->lpProvider, nra.lpProvider);
|
|
if((!nra.lpLocalName && lpnrw->lpLocalName) ||
|
|
(!nra.lpLocalName && lpnrw->lpLocalName) ||
|
|
(!nra.lpLocalName && lpnrw->lpLocalName) ||
|
|
(!nra.lpLocalName && lpnrw->lpLocalName))
|
|
{
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(ERROR_EXTENDED_ERROR);
|
|
}
|
|
|
|
// Set up the buffer if there is one, otherwise
|
|
// pass NULL to try to get a buffer size
|
|
if(lpcbBuffer && *lpcbBuffer)
|
|
{
|
|
_STACKALLOC(*lpcbBuffer, lpBufferAnsi);
|
|
if(lpBufferAnsi==NULL)
|
|
{
|
|
return(ERROR_STACK_OVERFLOW);
|
|
}
|
|
}
|
|
else
|
|
lpBufferAnsi = NULL;
|
|
|
|
// Call the API
|
|
RetVal=WNetGetResourceParentA(&nra, lpBufferAnsi, lpcbBuffer);
|
|
|
|
// Begin postcall
|
|
if(RetVal==NO_ERROR)
|
|
{
|
|
// Set up our NETRESOURCE vars, a valid lpBufferAnsi is implied here
|
|
lpnraOut = lpBufferAnsi;
|
|
lprnw = lpBuffer;
|
|
|
|
// Copy the first four (non-string) parameters and set the offset
|
|
memcpy(lpnrw, lpnraOut, (4*sizeof(DWORD)));
|
|
dwOffset = sizeof(NETRESOURCEW);
|
|
|
|
// Local name
|
|
if(FSTRING_VALID(lpnraOut->lpLocalName))
|
|
{
|
|
lpwz = (LPWSTR)&lprnw + dwOffset;
|
|
MultiByteToWideChar(g_acp, 0, lpnraOut->lpLocalName, -1, lpwz, -1);
|
|
dwOffset += (lpwz ? gwcslen(lpwz) + 1 : 0);
|
|
lpnrw->lpLocalName = lpwz;
|
|
}
|
|
|
|
// Remote name
|
|
if(FSTRING_VALID(lpnraOut->lpRemoteName))
|
|
{
|
|
lpwz = (LPWSTR)&lprnw + dwOffset;
|
|
MultiByteToWideChar(g_acp, 0, lpnraOut->lpRemoteName, -1, lpwz, -1);
|
|
dwOffset += (lpwz ? gwcslen(lpwz) + 1 : 0);
|
|
lpnrw->lpRemoteName = lpwz;
|
|
}
|
|
|
|
// Comment
|
|
if(FSTRING_VALID(lpnraOut->lpComment))
|
|
{
|
|
lpwz = (LPWSTR)&lprnw + dwOffset;
|
|
MultiByteToWideChar(g_acp, 0, lpnraOut->lpComment, -1, lpwz, -1);
|
|
dwOffset += (lpwz ? gwcslen(lpwz) + 1 : 0);
|
|
lpnrw->lpComment = lpwz;
|
|
}
|
|
|
|
// Provider
|
|
if(FSTRING_VALID(lpnraOut->lpProvider))
|
|
{
|
|
lpwz = (LPWSTR)&lprnw + dwOffset;
|
|
MultiByteToWideChar(g_acp, 0, lpnraOut->lpProvider, -1, lpwz, -1);
|
|
dwOffset += (lpwz ? gwcslen(lpwz) + 1 : 0);
|
|
lpnrw->lpProvider = lpwz;
|
|
}
|
|
|
|
}
|
|
else if (RetVal==ERROR_MORE_DATA && lpcbBuffer)
|
|
{
|
|
// We do not know the exact size here, so out best guess is the
|
|
// size of the "A" buffer we get back, *2 for all of the structure
|
|
// past the NETRESOURCEA part.
|
|
*lpcbBuffer = (sizeof(NETRESOURCEA) +
|
|
((*lpcbBuffer - (sizeof(NETRESOURCEA))) * sizeof(WCHAR)));
|
|
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=WNetGetUserW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotWNetGetUserW(LPCWSTR lpName, LPWSTR lpUserName, LPDWORD lpnLength)
|
|
{
|
|
DWORD RetVal;
|
|
LPSTR lpNameAnsi;
|
|
LPSTR lpUserNameAnsi;
|
|
DWORD nLength;
|
|
|
|
if(!lpnLength)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return(0);
|
|
}
|
|
|
|
nLength = *lpnLength;
|
|
GODOT_TO_ACP_STACKALLOC(lpName, lpNameAnsi);
|
|
|
|
// Alloc buffer, assume caller is being honest about size
|
|
_STACKALLOC((nLength *g_mcs)+1, lpUserNameAnsi);
|
|
|
|
RetVal=WNetGetUserA(lpNameAnsi, lpUserNameAnsi, &nLength);
|
|
|
|
if(RetVal==WN_NO_ERROR)
|
|
{
|
|
if (*lpnLength >= nLength)
|
|
{
|
|
// Success and buffer was big enough
|
|
MultiByteToWideChar(g_acp, 0, lpUserNameAnsi, nLength, lpUserName, *lpnLength);
|
|
*lpnLength = gwcslen(lpUserName);
|
|
}
|
|
else
|
|
{
|
|
// It was not real success, as their buffer was not large enough
|
|
RetVal=ERROR_MORE_DATA;
|
|
*lpnLength = nLength;
|
|
}
|
|
}
|
|
else
|
|
*lpnLength = nLength;
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=WNetOpenEnumW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotWNetOpenEnumW(DWORD dwScope, DWORD dwType, DWORD dwUsage, LPNETRESOURCEW lpnrw, LPHANDLE lphEnum)
|
|
{
|
|
NETRESOURCEA nra;
|
|
|
|
ZeroMemory(&nra, sizeof(NETRESOURCEA));
|
|
memcpy(&nra, lpnrw, (4*sizeof(DWORD)));
|
|
GODOT_TO_ACP_STACKALLOC(lpnrw->lpLocalName, nra.lpLocalName);
|
|
GODOT_TO_ACP_STACKALLOC(lpnrw->lpRemoteName, nra.lpRemoteName);
|
|
GODOT_TO_ACP_STACKALLOC(lpnrw->lpComment, nra.lpComment);
|
|
GODOT_TO_ACP_STACKALLOC(lpnrw->lpProvider, nra.lpProvider);
|
|
if((!nra.lpLocalName && lpnrw->lpLocalName) ||
|
|
(!nra.lpLocalName && lpnrw->lpLocalName) ||
|
|
(!nra.lpLocalName && lpnrw->lpLocalName) ||
|
|
(!nra.lpLocalName && lpnrw->lpLocalName))
|
|
{
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(ERROR_EXTENDED_ERROR);
|
|
}
|
|
|
|
// Call the 'A' version of the API
|
|
return(WNetOpenEnumA(dwScope, dwType, dwUsage, &nra, lphEnum));
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=WNetUseConnectionW
|
|
Begin=
|
|
DWORD __stdcall
|
|
GodotWNetUseConnectionW( HWND hwndOwner,
|
|
LPNETRESOURCEW lpnrw,
|
|
LPCWSTR lpUserID,
|
|
LPCWSTR lpPassword,
|
|
DWORD dwFlags,
|
|
LPWSTR lpAccessName,
|
|
LPDWORD lpBufferSize,
|
|
LPDWORD lpResult
|
|
)
|
|
{
|
|
// Begin locals
|
|
DWORD RetVal;
|
|
LPSTR lpUserIDAnsi;
|
|
LPSTR lpPasswordAnsi;
|
|
NETRESOURCEA nra;
|
|
LPSTR lpAccessNameAnsi;
|
|
|
|
// Begin precall
|
|
ZeroMemory(&nra, sizeof(NETRESOURCEA));
|
|
memcpy(&nra, lpnrw, (4*sizeof(DWORD)));
|
|
GODOT_TO_ACP_STACKALLOC(lpnrw->lpLocalName, nra.lpLocalName);
|
|
GODOT_TO_ACP_STACKALLOC(lpnrw->lpRemoteName, nra.lpRemoteName);
|
|
GODOT_TO_ACP_STACKALLOC(lpnrw->lpComment, nra.lpComment);
|
|
GODOT_TO_ACP_STACKALLOC(lpnrw->lpProvider, nra.lpProvider);
|
|
GODOT_TO_ACP_STACKALLOC(lpUserID, lpUserIDAnsi);
|
|
GODOT_TO_ACP_STACKALLOC(lpPassword, lpPasswordAnsi);
|
|
if((!nra.lpLocalName && lpnrw->lpLocalName) ||
|
|
(!nra.lpLocalName && lpnrw->lpLocalName) ||
|
|
(!nra.lpLocalName && lpnrw->lpLocalName) ||
|
|
(!nra.lpLocalName && lpnrw->lpLocalName) ||
|
|
(!lpUserIDAnsi && lpUserID) ||
|
|
(!lpPasswordAnsi && lpPassword))
|
|
{
|
|
SetLastError(ERROR_STACK_OVERFLOW);
|
|
return(ERROR_EXTENDED_ERROR);
|
|
}
|
|
|
|
// Alloc buffer, assume caller is being honest about size
|
|
_STACKALLOC((*lpBufferSize*g_mcs)+1, lpAccessNameAnsi);
|
|
|
|
// IMPORTANT! Per PSDK: Windows 95/98:
|
|
// The lpUserID and lpPassword parameters are in reverse order from the order used
|
|
// on Windows NT/Windows 2000.
|
|
// Thus, we reverse the order
|
|
|
|
RetVal=WNetUseConnectionA(hwndOwner,
|
|
&nra,
|
|
lpPasswordAnsi,
|
|
lpUserIDAnsi,
|
|
dwFlags,
|
|
lpAccessNameAnsi,
|
|
lpBufferSize,
|
|
lpResult
|
|
);
|
|
|
|
if(RetVal==NO_ERROR)
|
|
{
|
|
MultiByteToWideChar(g_acp, 0, lpAccessNameAnsi, -1, lpAccessName, *lpBufferSize);
|
|
*lpBufferSize = gwcslen(lpAccessName);
|
|
}
|
|
else if(RetVal==ERROR_MORE_DATA)
|
|
{
|
|
// Since *lpBufferSize is the size in cch, we should be able to live with it
|
|
}
|
|
|
|
// Finished
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=wvsprintfW
|
|
Begin=
|
|
|
|
// Stolen from wsprintf.c in the NT sources
|
|
|
|
#define WSPRINTF_LIMIT 1024
|
|
const ULONG MAX_ULONG = 0xFFFFFFFF;
|
|
#define MAXULONG MAX_ULONG
|
|
#define out(c) if (cchLimit) {*lpOut++=(c); cchLimit--;} else goto errorout
|
|
|
|
int __stdcall
|
|
GodotwvsprintfW(LPWSTR lpOut, LPCWSTR lpFmt, va_list arglist)
|
|
{
|
|
BOOL fAllocateMem;
|
|
WCHAR prefix, fillch;
|
|
int left, width, prec, size, sign, radix, upper, hprefix;
|
|
int cchLimit = WSPRINTF_LIMIT, cch;
|
|
LPWSTR lpT;
|
|
LPWSTR lpTWC = NULL;
|
|
LPBYTE psz;
|
|
va_list varglist = arglist;
|
|
union {
|
|
LONG64 l;
|
|
ULONG64 ul;
|
|
char sz[2];
|
|
WCHAR wsz[2];
|
|
} val;
|
|
|
|
while (*lpFmt != 0)
|
|
{
|
|
if (*lpFmt == L'%')
|
|
{
|
|
|
|
/*
|
|
* read the flags. These can be in any order
|
|
*/
|
|
left = 0;
|
|
prefix = 0;
|
|
while (*++lpFmt)
|
|
{
|
|
if (*lpFmt == L'-')
|
|
left++;
|
|
else if (*lpFmt == L'#')
|
|
prefix++;
|
|
else
|
|
break;
|
|
}
|
|
|
|
/*
|
|
* find fill character
|
|
*/
|
|
if (*lpFmt == L'0')
|
|
{
|
|
fillch = L'0';
|
|
lpFmt++;
|
|
} else
|
|
fillch = L' ';
|
|
|
|
/*
|
|
* read the width specification
|
|
*/
|
|
lpFmt = SP_GetFmtValueW(lpFmt, &cch);
|
|
width = cch;
|
|
|
|
/*
|
|
* read the precision
|
|
*/
|
|
if (*lpFmt == L'.')
|
|
{
|
|
lpFmt = SP_GetFmtValueW(++lpFmt, &cch);
|
|
prec = cch;
|
|
} else
|
|
prec = -1;
|
|
|
|
/*
|
|
* get the operand size
|
|
* default size: size == 0
|
|
* long number: size == 1
|
|
* wide chars: size == 2
|
|
* 64bit number: size == 3
|
|
* It may be a good idea to check the value of size when it
|
|
* is tested for non-zero below (IanJa)
|
|
*/
|
|
hprefix = 0;
|
|
if ((*lpFmt == L'w') || (*lpFmt == L't'))
|
|
{
|
|
size = 2;
|
|
lpFmt++;
|
|
}
|
|
else if (*lpFmt == L'l')
|
|
{
|
|
size = 1;
|
|
lpFmt++;
|
|
}
|
|
else if (*lpFmt == L'I')
|
|
{
|
|
if (*(lpFmt+1) == L'3' && *(lpFmt+2) == L'2')
|
|
{
|
|
size = 1;
|
|
lpFmt += 3;
|
|
}
|
|
else if (*(lpFmt+1) == L'6' && *(lpFmt+2) == L'4')
|
|
{
|
|
size = 3;
|
|
lpFmt += 3;
|
|
}
|
|
else
|
|
{
|
|
size = (sizeof(INT_PTR) == sizeof(LONG)) ? 1 : 3;
|
|
lpFmt++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
size = 0;
|
|
if (*lpFmt == L'h')
|
|
{
|
|
lpFmt++;
|
|
hprefix = 1;
|
|
}
|
|
else if ((*lpFmt == L'i') || (*lpFmt == L'd'))
|
|
{
|
|
// %i or %d specified (no modifiers) - use long
|
|
// %u seems to have always been short - leave alone
|
|
size = 1;
|
|
}
|
|
}
|
|
|
|
upper = 0;
|
|
sign = 0;
|
|
radix = 10;
|
|
|
|
switch (*lpFmt)
|
|
{
|
|
case 0:
|
|
goto errorout;
|
|
|
|
case L'i':
|
|
case L'd':
|
|
sign++;
|
|
|
|
/*** FALL THROUGH to case 'u' ***/
|
|
|
|
case L'u':
|
|
/* turn off prefix if decimal */
|
|
prefix = 0;
|
|
donumeric:
|
|
/* special cases to act like MSC v5.10 */
|
|
if (left || prec >= 0)
|
|
fillch = L' ';
|
|
|
|
/*
|
|
* if size == 1, "%lu" was specified (good);
|
|
* if size == 2, "%wu" was specified (bad)
|
|
* if size == 3, "%p" was specified
|
|
*/
|
|
if (size == 3)
|
|
{
|
|
val.l = va_arg(varglist, LONG64);
|
|
}
|
|
else if (size)
|
|
{
|
|
val.l = va_arg(varglist, LONG);
|
|
}
|
|
else if (sign)
|
|
{
|
|
val.l = va_arg(varglist, SHORT);
|
|
}
|
|
else
|
|
{
|
|
val.ul = va_arg(varglist, unsigned);
|
|
}
|
|
|
|
if (sign && val.l < 0L)
|
|
val.l = -val.l;
|
|
else
|
|
sign = 0;
|
|
|
|
/*
|
|
* Unless printing a full 64-bit value, ensure values
|
|
* here are not in canonical longword format to prevent
|
|
* the sign extended upper 32-bits from being printed.
|
|
*/
|
|
if (size != 3)
|
|
{
|
|
val.l &= MAXULONG;
|
|
}
|
|
|
|
lpT = lpOut;
|
|
|
|
/*
|
|
* blast the number backwards into the user buffer
|
|
*/
|
|
cch = SP_PutNumberW(lpOut, val.l, cchLimit, radix, upper);
|
|
if (!(cchLimit -= cch))
|
|
goto errorout;
|
|
|
|
lpOut += cch;
|
|
width -= cch;
|
|
prec -= cch;
|
|
if (prec > 0)
|
|
width -= prec;
|
|
|
|
/*
|
|
* fill to the field precision
|
|
*/
|
|
while (prec-- > 0)
|
|
out(L'0');
|
|
|
|
if (width > 0 && !left)
|
|
{
|
|
/*
|
|
* if we're filling with spaces, put sign first
|
|
*/
|
|
if (fillch != L'0')
|
|
{
|
|
if (sign)
|
|
{
|
|
sign = 0;
|
|
out(L'-');
|
|
width--;
|
|
}
|
|
|
|
if (prefix)
|
|
{
|
|
out(prefix);
|
|
out(L'0');
|
|
prefix = 0;
|
|
}
|
|
}
|
|
|
|
if (sign)
|
|
width--;
|
|
|
|
/*
|
|
* fill to the field width
|
|
*/
|
|
while (width-- > 0)
|
|
out(fillch);
|
|
|
|
/*
|
|
* still have a sign?
|
|
*/
|
|
if (sign)
|
|
out(L'-');
|
|
|
|
if (prefix)
|
|
{
|
|
out(prefix);
|
|
out(L'0');
|
|
}
|
|
|
|
/*
|
|
* now reverse the string in place
|
|
*/
|
|
SP_ReverseW(lpT, lpOut - 1);
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* add the sign character
|
|
*/
|
|
if (sign)
|
|
{
|
|
out(L'-');
|
|
width--;
|
|
}
|
|
|
|
if (prefix)
|
|
{
|
|
out(prefix);
|
|
out(L'0');
|
|
}
|
|
|
|
/*
|
|
* reverse the string in place
|
|
*/
|
|
SP_ReverseW(lpT, lpOut - 1);
|
|
|
|
/*
|
|
* pad to the right of the string in case left aligned
|
|
*/
|
|
while (width-- > 0)
|
|
out(fillch);
|
|
}
|
|
break;
|
|
|
|
case L'p':
|
|
size = (sizeof(PVOID) == sizeof(LONG)) ? 1 : 3;
|
|
if (prec == -1)
|
|
{
|
|
prec = 2 * sizeof(PVOID);
|
|
}
|
|
|
|
/*** FALL THROUGH to case 'X' ***/
|
|
|
|
case L'X':
|
|
upper++;
|
|
|
|
/*** FALL THROUGH to case 'x' ***/
|
|
|
|
case L'x':
|
|
radix = 16;
|
|
if (prefix)
|
|
if (upper)
|
|
prefix = L'X';
|
|
else
|
|
prefix = L'x';
|
|
goto donumeric;
|
|
|
|
case L'c':
|
|
if (!size && !hprefix)
|
|
{
|
|
size = 1; // force WCHAR
|
|
}
|
|
|
|
/*** FALL THROUGH to case 'C' ***/
|
|
|
|
case L'C':
|
|
/*
|
|
* if size == 0, "%C" or "%hc" was specified (CHAR);
|
|
* if size == 1, "%c" or "%lc" was specified (WCHAR);
|
|
* if size == 2, "%wc" or "%tc" was specified (WCHAR)
|
|
*/
|
|
cch = 1; /* One character must be copied to the output buffer */
|
|
if (size)
|
|
{
|
|
val.wsz[0] = va_arg(varglist, WCHAR);
|
|
val.wsz[1] = 0;
|
|
lpT = val.wsz;
|
|
goto putwstring;
|
|
}
|
|
else
|
|
{
|
|
val.sz[0] = va_arg(varglist, CHAR);
|
|
val.sz[1] = 0;
|
|
psz = (LPBYTE)val.sz;
|
|
goto putstring;
|
|
}
|
|
|
|
case L's':
|
|
if (!size && !hprefix)
|
|
{
|
|
size = 1; // force LPWSTR
|
|
}
|
|
|
|
/*** FALL THROUGH to case 'S' ***/
|
|
|
|
case L'S':
|
|
/*
|
|
* if size == 0, "%S" or "%hs" was specified (LPSTR)
|
|
* if size == 1, "%s" or "%ls" was specified (LPWSTR);
|
|
* if size == 2, "%ws" or "%ts" was specified (LPWSTR)
|
|
*/
|
|
if (size)
|
|
{
|
|
lpT = va_arg(varglist, LPWSTR);
|
|
cch = gwcslen(lpT);
|
|
putwstring:
|
|
fAllocateMem = FALSE;
|
|
}
|
|
else
|
|
{
|
|
psz = va_arg(varglist, LPBYTE);
|
|
if (psz == NULL)
|
|
|
|
{
|
|
cch = 0;
|
|
}
|
|
else
|
|
{
|
|
cch = strlen((LPSTR)psz);
|
|
}
|
|
putstring:
|
|
lpTWC = GodotHeapAlloc(cch * sizeof(WCHAR));
|
|
if(lpTWC)
|
|
{
|
|
cch = MultiByteToWideChar(g_acp, 0, (LPSTR)psz, cch, lpTWC, cch);
|
|
fAllocateMem = TRUE;
|
|
}
|
|
else
|
|
{
|
|
cch = 0;
|
|
fAllocateMem = FALSE;
|
|
|
|
}
|
|
lpT = lpTWC;
|
|
}
|
|
|
|
if (prec >= 0 && cch > prec)
|
|
cch = prec;
|
|
width -= cch;
|
|
|
|
if (fAllocateMem)
|
|
{
|
|
if (cch + (width < 0 ? 0 : width) >= cchLimit)
|
|
{
|
|
GodotHeapFree(lpTWC);
|
|
goto errorout;
|
|
}
|
|
}
|
|
|
|
if (left)
|
|
{
|
|
while (cch--)
|
|
out(*lpT++);
|
|
while (width-- > 0)
|
|
out(fillch);
|
|
}
|
|
else
|
|
{
|
|
while (width-- > 0)
|
|
out(fillch);
|
|
while (cch--)
|
|
out(*lpT++);
|
|
}
|
|
|
|
if (fAllocateMem)
|
|
{
|
|
GodotHeapFree(lpTWC);
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
normalch:
|
|
out((WCHAR)*lpFmt);
|
|
break;
|
|
} /* END OF SWITCH(*lpFmt) */
|
|
} /* END OF IF(%) */
|
|
else
|
|
goto normalch; /* character not a '%', just do it */
|
|
|
|
/*
|
|
* advance to next format string character
|
|
*/
|
|
lpFmt++;
|
|
} /* END OF OUTER WHILE LOOP */
|
|
|
|
errorout:
|
|
*lpOut = 0;
|
|
|
|
return WSPRINTF_LIMIT - cchLimit;
|
|
}
|
|
|
|
End=
|
|
|
|
[EFunc]
|
|
TemplateName=wsprintfW
|
|
Begin=
|
|
int _cdecl
|
|
GodotwsprintfW(LPWSTR lpOut, LPCWSTR lpFmt, ... )
|
|
{
|
|
va_list arglist;
|
|
int RetVal;
|
|
|
|
va_start(arglist, lpFmt);
|
|
RetVal = GodotwvsprintfW(lpOut, lpFmt, arglist);
|
|
va_end(arglist);
|
|
return RetVal;
|
|
}
|
|
|
|
End=
|
|
|