|
|
1.1 root 1: /*++
2:
3: Copyright (c) 1985-92, Microsoft Corporation
4:
5: Module Name:
6:
7: UTSamp32.c
8:
9: Abstract:
10:
11: Win32s sample code of Universal Thunk (UT) -
12: This is the main source file of UTSamp32.DLL
13:
14: --*/
15:
16:
17: #define W32SUT_32
18:
19: #include <windows.h>
20: #include <w32sut.h>
21: #include "utsamp.h"
22:
23: typedef BOOL (WINAPI * PUTREGISTER) ( HANDLE hModule,
24: LPCSTR lpsz16BitDLL,
25: LPCSTR lpszInitName,
26: LPCSTR lpszProcName,
27: UT32PROC * ppfn32Thunk,
28: FARPROC pfnUT32Callback,
29: LPVOID lpBuff
30: );
31:
32:
33: typedef VOID (WINAPI * PUTUNREGISTER) (HANDLE hModule);
34:
35: UT32PROC pfnUTProc = NULL;
36: PUTREGISTER pUTRegister = NULL;
37: PUTUNREGISTER pUTUnRegister = NULL;
38: int cProcessesAttached = 0;
39: BOOL fWin32s = FALSE;
40: HANDLE hKernel32 = 0;
41:
42:
43: BOOL
44: APIENTRY
45: DllInit(HANDLE hInst, DWORD fdwReason, LPVOID lpReserved)
46: {
47: if ( fdwReason == DLL_PROCESS_ATTACH )
48: {
49:
50: /*
51: * Registration of UT need to be done only once for first
52: * attaching process. At that time set the fWin32s flag
53: * to indicate if the DLL is executing under Win32s or not.
54: * If we are running under WIn32s, we need to get the
55: * address of the entrypoints for UTRegister & UTUnRegister
56: *
57: */
58:
59: if ( cProcessesAttached++ )
60: {
61: return(TRUE); // Not the first initialization.
62: }
63:
64: fWin32s = (BOOL) (GetVersion() & 0x80000000);
65:
66: if ( !fWin32s )
67: return(TRUE); // Not on Win32s - no further initialization needed
68:
69: hKernel32 = LoadLibrary( "Kernel32.Dll" ); // Get Handle to Kernel32.Dll
70:
71: pUTRegister = (PUTREGISTER) GetProcAddress( hKernel32, "UTRegister" );
72:
73: if ( !pUTRegister )
74: return(FALSE); // Error - On Win32s, can't find UTRegister
75:
76: pUTUnRegister = (PUTUNREGISTER) GetProcAddress( hKernel32, "UTUnRegister" );
77:
78: if ( !pUTUnRegister )
79: return(FALSE); // Error - On Win32s, can't find UTUnRegister
80:
81: return (*pUTRegister)( hInst, // UTSamp32.DLL module handle
82: "UTSAMP16.DLL", // name of 16bit thunk dll
83: NULL, // no init routine
84: "UTProc", // name of 16bit dispatch routine
85: // exported from UTSamp16.DLL
86: &pfnUTProc, // Global variable to receive thunk address
87: NULL, // no callback function
88: NULL ); // no shared memroy
89:
90: }
91: else
92: if ( (fdwReason == DLL_PROCESS_DETACH)
93: && (0 == --cProcessesAttached)
94: && fWin32s )
95: {
96: (*pUTUnRegister) ( hInst );
97: FreeLibrary( hKernel32 );
98: }
99:
100: }
101:
102:
103: DWORD
104: APIENTRY
105: MyGetFreeSpace(void)
106: {
107: MEMORYSTATUS MemoryStatus;
108:
109: /*
110: * Call GlobalMemoryStatus to get the amount of free physical memory. Since
111: * GlobalMemoryStatus does not have a return value, the way to check for
112: * failure is to SetLastError to NO_ERROR, call GlobalMemoryStatus, and then
113: * GetLastError to see if ERROR_CALL_NOT_IMPLEMENTED was returned. If so,
114: * and if Win32s is loaded, call the UT entrypoint passing MYGETFREESPACE
115: * as the parameter.
116: *
117: */
118:
119: memset( &MemoryStatus, sizeof(MEMORYSTATUS), 0);
120: SetLastError( NO_ERROR );
121: GlobalMemoryStatus( &MemoryStatus );
122: if (ERROR_CALL_NOT_IMPLEMENTED == GetLastError() && fWin32s)
123: return( (* pfnUTProc)( NULL, MYGETFREESPACE, NULL ) );
124: else
125: return( MemoryStatus.dwAvailPhys );
126: }
127:
128: DWORD
129: APIENTRY
130: MyWNetGetUser(LPTSTR lpszLocalName, LPTSTR lpszUserName, LPDWORD lpcchBuffer)
131: {
132:
133: DWORD Args[2];
134: PVOID TransList[3];
135: DWORD retval;
136:
137: /*
138: * Since the Win16 WNetGetUser does not support the lpszLocalName,
139: * this parameter is ignored by this function when called under Win32s.
140: * It is accepted for compatibility with the Win32 API.
141: *
142: * The error return method for the this API changed between Win16 and Win32.
143: * Win16 uses several different return codes to indicate different errors,
144: * while Win32 uses only a few return codes to indicate error, one of which
145: * indicates that WNetGetLastError should be called for more detailed error
146: * information.
147: *
148: * This function just maps all Win16 error codes into the Win32 error
149: * ERROR_NO_NETWORK. A more complete solution would be to switch on the
150: * various return codes possible from WNetGetUser (both Win16 & Win32) and
151: * to set appropriate SetLastError values.
152: *
153: */
154:
155:
156: if (ERROR_CALL_NOT_IMPLEMENTED ==
157: (retval = WNetGetUser( lpszLocalName, lpszUserName, lpcchBuffer )))
158: {
159:
160: /*
161: * call the 16bit WNetGetUser via the UT entrypoint.
162: * Since the parameters being passed include pointers that need to be
163: * translated, we need to use the Translation List.
164: *
165: */
166:
167: Args[0] = (DWORD)lpszUserName; // Buffer to receive UserName
168: Args[1] = (DWORD)lpcchBuffer; // Pointer to a DWord containing the size
169: // of this buffer on entry. On return it will
170: // have been replaced with the size of the
171: // returned text. Since the Win16 API only
172: // changes the low 16 bits, we need to zero out
173: // the high 16 bits before calling the API.
174:
175: if ((*lpcchBuffer) > 0xFFFF) // The buffer could be 64K or larger, but
176: { // since the API only looks at the lower
177: *lpcchBuffer = 0xFFFF; // 16 bits passed, we need to make sure the
178: } // buffer is not too large.
179:
180: TransList[0] = & Args[0]; // Translate the two pointes passed in Args[]
181: TransList[1] = & Args[1]; // from 0:32 to 16:16.
182: TransList[2] = NULL; // End of list of pointers to translate
183:
184: retval = (* pfnUTProc)(Args, MYWNETGETUSER, TransList);
185:
186: if (retval) // WN_SUCCESS == NO_ERROR == 0. All others
187: retval = ERROR_NO_NETWORK; // return codes are Win16 error codes that
188: // we map to ERROR_NO_NETWORK.
189: }
190:
191: return (retval);
192:
193: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.