#include "npstub.h" #include #include #include #include /* message defs, class name */ #define ARRAYSIZE(x) (sizeof(x)/sizeof((x)[0])) HINSTANCE hInstance = NULL; HWND hwndMonitor = NULL; CRITICAL_SECTION critsec; ATOM aClass = NULL; #define ENTERCRITICAL EnterCriticalSection(&::critsec); #define LEAVECRITICAL LeaveCriticalSection(&::critsec); UINT cCallsInProgress = 0; BOOL fShouldUnload = FALSE; /* This chunk of code invokes the entrypoint hooking feature of MPR. We hook * things and immediately unhook ourselves. We don't really want to hook * any functionality, this is just a way to kick MPR so he'll redetermine * the capabilities (via NPGetCaps) of all the net providers, including * ours. */ F_NPSHookMPR HookHookMPR; F_UnHookMPR HookUnHookMPR; F_LoadLibrary HookLoadLibrary; F_FreeLibrary HookFreeLibrary; F_GetProcAddress HookGetProcAddress; F_LoadLibrary16 HookWMLoadWinnet16; F_FreeLibrary16 HookWMFreeWinnet16; F_GetProcAddressByName16 HookWMGetProcAddressByName; F_GetProcAddressByOrdinal16 HookWMGetProcAddressByOrdinal; MPRCALLS MPRCalls = { HookHookMPR, HookUnHookMPR, HookLoadLibrary, HookFreeLibrary, HookGetProcAddress, HookWMLoadWinnet16, HookWMFreeWinnet16, HookWMGetProcAddressByName, HookWMGetProcAddressByOrdinal }; DWORD NPSERVICE HookHookMPR ( PMPRCALLS pMPRCalls ) { return ((PF_NPSHookMPR)(MPRCalls.pfNPSHookMPR))(pMPRCalls); } DWORD NPSERVICE HookUnHookMPR ( PF_NPSHookMPR pfReqNPSHookMPR, PMPRCALLS pReqMPRCalls ) { if (pfReqNPSHookMPR == HookHookMPR) { // The unhook request has reached the hooker that issued // the NPSUnHookMe call (us). // In other words we are now sucessfully unhooked // and may do our unhooking cleanup. // In particular, we can release our tables that // manage LoadLibrary/GetProcAddress. // Note that this code may be executing on a different // thread to the NPSUnHookMe call which may have returned // a while ago. return WN_SUCCESS; } else { // Another hooker has requested to unhook by calling // NPSUnHookMe which causes us to be called here. // Pass the request on to the MPR service NPSUnHookMPR to // process the request, giving it our MPRCALLS // data structure so that it can figure out if // we are the right hooker to update and otherwise // MPR will pass the request on to the next hooker. return NPSUnHookMPR ( pfReqNPSHookMPR, pReqMPRCalls, (PMPRCALLS)&MPRCalls ); } } HINSTANCE HookLoadLibrary( LPCTSTR lpszLibFile ) { return MPRCalls.pfLoadLibrary(lpszLibFile); } BOOL HookFreeLibrary( HMODULE hLibModule ) { return MPRCalls.pfFreeLibrary(hLibModule); } FARPROC HookGetProcAddress( HMODULE hModule, LPCSTR lpszProc ) { return MPRCalls.pfGetProcAddress(hModule, lpszProc); } HANDLE16 HookWMLoadWinnet16( LPCTSTR lpszLibFile ) { return MPRCalls.pfLoadLibrary16(lpszLibFile); } VOID HookWMFreeWinnet16( HANDLE16 hLibModule ) { MPRCalls.pfFreeLibrary16(hLibModule); } DWORD WINAPI HookWMGetProcAddressByName( LPCSTR lpszProc, HANDLE16 hModule ) { return MPRCalls.pfGetProcAddressByName16(lpszProc, hModule); } DWORD WINAPI HookWMGetProcAddressByOrdinal( WORD wOrdinal, HANDLE16 hModule ) { return MPRCalls.pfGetProcAddressByOrdinal16(wOrdinal, hModule); } void KickMPR(void) { if (NPSHookMPR((PMPRCALLS)&MPRCalls) == WN_SUCCESS) { NPSUnHookMe(HookHookMPR, (PMPRCALLS)&MPRCalls); } } /***** End MPR hooking code *****/ /***** Begin code to delay-load the real net provider DLL *****/ HMODULE hmodRealNP = NULL; PF_NPGetCaps pfnNPGetCaps = NULL; PF_NPGetUniversalName pfnNPGetUniversalName = NULL; PF_NPGetUser pfnNPGetUser = NULL; PF_NPValidLocalDevice pfnNPValidLocalDevice = NULL; PF_NPAddConnection pfnNPAddConnection = NULL; PF_NPCancelConnection pfnNPCancelConnection = NULL; PF_NPGetConnection pfnNPGetConnection = NULL; PF_NPGetConnectionPerformance pfnNPGetConnectionPerformance = NULL; PF_NPFormatNetworkName pfnNPFormatNetworkName = NULL; PF_NPOpenEnum pfnNPOpenEnum = NULL; PF_NPEnumResource pfnNPEnumResource = NULL; PF_NPCloseEnum pfnNPCloseEnum = NULL; PF_NPGetResourceParent pfnNPGetResourceParent = NULL; PF_NPGetResourceInformation pfnNPGetResourceInformation = NULL; PF_NPLogon pfnNPLogon = NULL; PF_NPLogoff pfnNPLogoff = NULL; PF_NPGetHomeDirectory pfnNPGetHomeDirectory = NULL; PF_NPGetPolicyPath pfnNPGetPolicyPath = NULL; struct { UINT nOrd; FARPROC *ppfn; } aProcs[] = { { ORD_GETCAPS, (FARPROC *)&pfnNPGetCaps }, { ORD_GETUNIVERSALNAME, (FARPROC *)&pfnNPGetUniversalName }, { ORD_GETUSER, (FARPROC *)&pfnNPGetUser }, { ORD_VALIDDEVICE, (FARPROC *)&pfnNPValidLocalDevice }, { ORD_ADDCONNECTION, (FARPROC *)&pfnNPAddConnection }, { ORD_CANCELCONNECTION, (FARPROC *)&pfnNPCancelConnection }, { ORD_GETCONNECTIONS, (FARPROC *)&pfnNPGetConnection }, { ORD_GETCONNPERFORMANCE, (FARPROC *)&pfnNPGetConnectionPerformance }, { ORD_FORMATNETWORKNAME, (FARPROC *)&pfnNPFormatNetworkName }, { ORD_OPENENUM, (FARPROC *)&pfnNPOpenEnum }, { ORD_ENUMRESOURCE, (FARPROC *)&pfnNPEnumResource }, { ORD_CLOSEENUM, (FARPROC *)&pfnNPCloseEnum }, { ORD_GETRESOURCEPARENT, (FARPROC *)&pfnNPGetResourceParent }, { ORD_GETRESOURCEINFORMATION, (FARPROC *)&pfnNPGetResourceInformation }, { ORD_LOGON, (FARPROC *)&pfnNPLogon }, { ORD_LOGOFF, (FARPROC *)&pfnNPLogoff }, { ORD_GETHOMEDIRECTORY, (FARPROC *)&pfnNPGetHomeDirectory }, { ORD_GETPOLICYPATH, (FARPROC *)&pfnNPGetPolicyPath }, }; void LoadRealNP(void) { ENTERCRITICAL if (::hmodRealNP == NULL) { char szDLLName[MAX_PATH]; szDLLName[0] = '\0'; HKEY hkeySection; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\NPSTUB\\NetworkProvider", 0, KEY_QUERY_VALUE, &hkeySection) == ERROR_SUCCESS) { DWORD dwType; DWORD cbData = sizeof(szDLLName); RegQueryValueEx(hkeySection, "RealDLL", NULL, &dwType, (LPBYTE)szDLLName, &cbData); RegCloseKey(hkeySection); } if (szDLLName[0] == '\0') lstrcpy(szDLLName, "mslocusr.dll"); ::hmodRealNP = LoadLibrary(szDLLName); if (::hmodRealNP != NULL) { for (UINT i=0; i 0) { fShouldUnload = TRUE; } else { for (UINT i=0; i