Listing 2 Implementing SetCurrentDirectoryW() for SharedCU, Redefine and DLL models
#ifdef WDN_SHAREDCU # define SetCurrentDirectoryW_impl SetCurrentDirectoryW . . . #endif /* WDN_SHAREDCU */ . . . /* Loads KERNEL32.DLL and returns its instance handle. There's no * release, but that's ok with KERNEL32.DLL, since every process * must be statically linked to it in order to be able to call * LoadLibrary() in the first place! Hacky, but valid. */ static HINSTANCE GetInstance_Kernel32(); static BOOL WINAPI SetCurrentDirectoryW_impl_9x(LPCWSTR lpPathName) { size_t len = lstrlenW(lpPathName); char *pathName = (char*)_alloca(1 + len); WideCharToMultiByte(CP_ACP, 0, lpPathName, 1 + len, pathName, 1 + len, NULL, NULL); return SetCurrentDirectoryA(pathName); } static BOOL WINAPI SetCurrentDirectoryW_impl_NT(LPCWSTR lpPathName) { #ifdef WDN_SHAREDCU /* In this mode, SetCurrentDirectoryW_impl is #defined to be SetCurrentDirectoryW, * so linking to SetCurrentDirectoryW would just result in infinite recursion * and stack exhaustion. It's unlikely that that process would result in the * desired directory change. * * Hence, we need to load SetCurrentDirectoryW from KERNEL32.DLL, and call it * in that way. */ typedef BOOL (WINAPI *PFnSetCurrentDirectoryW)(LPCWSTR lpFileName); PFnSetCurrentDirectoryW pfn = (PFnSetCurrentDirectoryW)GetProcAddress(GetInstance_Kernel32(), "SetCurrentDirectoryW"); return (NULL == pfn) ? FALSE : pfn(lpPathName); #else /* Otherwise just link to the function directly. */ return SetCurrentDirectoryW(lpPathName); #endif /* WDN_SHAREDCU */ } #ifdef WDN_SHAREDCU # pragma warning(disable : 4273) #endif /* WDN_SHAREDCU */ #ifdef WDN_DLL extern __declspec(dllexport) #endif /* WDN_DLL */ BOOL WINAPI SetCurrentDirectoryW_impl(LPCWSTR lpPathName) { if(IsWinNT()) { debug_printf("SetCurrentDirectoryW_impl(): calling NT's SetCurrentDirectoryW()\n"); return SetCurrentDirectoryW_impl_NT(lpPathName); } else { debug_printf("SetCurrentDirectoryW_impl(): calling SetCurrentDirectoryW_impl_9x()\n"); return SetCurrentDirectoryW_impl_9x(lpPathName); } } #ifdef WDN_SHAREDCU # pragma warning(default : 4273) #endif /* WDN_SHAREDCU */