|
|
Microsoft Windows NT Build 511 (SDK Final Release) 07-24-1993
/*++
Copyright (c) 1985-92, Microsoft Corporation
Module Name:
UTSamp32.c
Abstract:
Win32s sample code of Universal Thunk (UT) -
This is the main source file of UTSamp32.DLL
--*/
#define W32SUT_32
#include <windows.h>
#include <w32sut.h>
#include "utsamp.h"
typedef BOOL (WINAPI * PUTREGISTER) ( HANDLE hModule,
LPCSTR lpsz16BitDLL,
LPCSTR lpszInitName,
LPCSTR lpszProcName,
UT32PROC * ppfn32Thunk,
FARPROC pfnUT32Callback,
LPVOID lpBuff
);
typedef VOID (WINAPI * PUTUNREGISTER) (HANDLE hModule);
UT32PROC pfnUTProc = NULL;
PUTREGISTER pUTRegister = NULL;
PUTUNREGISTER pUTUnRegister = NULL;
int cProcessesAttached = 0;
BOOL fWin32s = FALSE;
HANDLE hKernel32 = 0;
BOOL
APIENTRY
DllInit(HANDLE hInst, DWORD fdwReason, LPVOID lpReserved)
{
if ( fdwReason == DLL_PROCESS_ATTACH )
{
/*
* Registration of UT need to be done only once for first
* attaching process. At that time set the fWin32s flag
* to indicate if the DLL is executing under Win32s or not.
* If we are running under WIn32s, we need to get the
* address of the entrypoints for UTRegister & UTUnRegister
*
*/
if ( cProcessesAttached++ )
{
return(TRUE); // Not the first initialization.
}
fWin32s = (BOOL) (GetVersion() & 0x80000000);
if ( !fWin32s )
return(TRUE); // Not on Win32s - no further initialization needed
hKernel32 = LoadLibrary( "Kernel32.Dll" ); // Get Handle to Kernel32.Dll
pUTRegister = (PUTREGISTER) GetProcAddress( hKernel32, "UTRegister" );
if ( !pUTRegister )
return(FALSE); // Error - On Win32s, can't find UTRegister
pUTUnRegister = (PUTUNREGISTER) GetProcAddress( hKernel32, "UTUnRegister" );
if ( !pUTUnRegister )
return(FALSE); // Error - On Win32s, can't find UTUnRegister
return (*pUTRegister)( hInst, // UTSamp32.DLL module handle
"UTSAMP16.DLL", // name of 16bit thunk dll
NULL, // no init routine
"UTProc", // name of 16bit dispatch routine
// exported from UTSamp16.DLL
&pfnUTProc, // Global variable to receive thunk address
NULL, // no callback function
NULL ); // no shared memroy
}
else
if ( (fdwReason == DLL_PROCESS_DETACH)
&& (0 == --cProcessesAttached)
&& fWin32s )
{
(*pUTUnRegister) ( hInst );
FreeLibrary( hKernel32 );
}
}
DWORD
APIENTRY
MyGetFreeSpace(void)
{
MEMORYSTATUS MemoryStatus;
/*
* Call GlobalMemoryStatus to get the amount of free physical memory. Since
* GlobalMemoryStatus does not have a return value, the way to check for
* failure is to SetLastError to NO_ERROR, call GlobalMemoryStatus, and then
* GetLastError to see if ERROR_CALL_NOT_IMPLEMENTED was returned. If so,
* and if Win32s is loaded, call the UT entrypoint passing MYGETFREESPACE
* as the parameter.
*
*/
memset( &MemoryStatus, sizeof(MEMORYSTATUS), 0);
SetLastError( NO_ERROR );
GlobalMemoryStatus( &MemoryStatus );
if (ERROR_CALL_NOT_IMPLEMENTED == GetLastError() && fWin32s)
return( (* pfnUTProc)( NULL, MYGETFREESPACE, NULL ) );
else
return( MemoryStatus.dwAvailPhys );
}
DWORD
APIENTRY
MyWNetGetUser(LPTSTR lpszLocalName, LPTSTR lpszUserName, LPDWORD lpcchBuffer)
{
DWORD Args[2];
PVOID TransList[3];
DWORD retval;
/*
* Since the Win16 WNetGetUser does not support the lpszLocalName,
* this parameter is ignored by this function when called under Win32s.
* It is accepted for compatibility with the Win32 API.
*
* The error return method for the this API changed between Win16 and Win32.
* Win16 uses several different return codes to indicate different errors,
* while Win32 uses only a few return codes to indicate error, one of which
* indicates that WNetGetLastError should be called for more detailed error
* information.
*
* This function just maps all Win16 error codes into the Win32 error
* ERROR_NO_NETWORK. A more complete solution would be to switch on the
* various return codes possible from WNetGetUser (both Win16 & Win32) and
* to set appropriate SetLastError values.
*
*/
if (ERROR_CALL_NOT_IMPLEMENTED ==
(retval = WNetGetUser( lpszLocalName, lpszUserName, lpcchBuffer )))
{
/*
* call the 16bit WNetGetUser via the UT entrypoint.
* Since the parameters being passed include pointers that need to be
* translated, we need to use the Translation List.
*
*/
Args[0] = (DWORD)lpszUserName; // Buffer to receive UserName
Args[1] = (DWORD)lpcchBuffer; // Pointer to a DWord containing the size
// of this buffer on entry. On return it will
// have been replaced with the size of the
// returned text. Since the Win16 API only
// changes the low 16 bits, we need to zero out
// the high 16 bits before calling the API.
if ((*lpcchBuffer) > 0xFFFF) // The buffer could be 64K or larger, but
{ // since the API only looks at the lower
*lpcchBuffer = 0xFFFF; // 16 bits passed, we need to make sure the
} // buffer is not too large.
TransList[0] = & Args[0]; // Translate the two pointes passed in Args[]
TransList[1] = & Args[1]; // from 0:32 to 16:16.
TransList[2] = NULL; // End of list of pointers to translate
retval = (* pfnUTProc)(Args, MYWNETGETUSER, TransList);
if (retval) // WN_SUCCESS == NO_ERROR == 0. All others
retval = ERROR_NO_NETWORK; // return codes are Win16 error codes that
// we map to ERROR_NO_NETWORK.
}
return (retval);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.