Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

251 lines
6.5 KiB

  1. #include <windows.h>
  2. #include "comdll.h"
  3. #include "ddraw.h"
  4. #include "ddrawex.h"
  5. UINT g_cRefDll = 0; // reference count for this DLL
  6. HANDLE g_hinst = NULL; // HMODULE for this DLL
  7. typedef struct {
  8. const IClassFactoryVtbl *cf;
  9. const CLSID *pclsid;
  10. HRESULT (STDMETHODCALLTYPE *pfnCreate)(IUnknown *, REFIID, void **);
  11. HRESULT (STDMETHODCALLTYPE *pfnRegUnReg)(BOOL bReg, HKEY hkCLSID, LPCSTR pszCLSID, LPCSTR pszModule);
  12. } OBJ_ENTRY;
  13. extern const IClassFactoryVtbl c_CFVtbl; // forward
  14. //
  15. // we always do a linear search here so put your most often used things first
  16. //
  17. const OBJ_ENTRY c_clsmap[] = {
  18. {&c_CFVtbl, &CLSID_DirectDrawFactory, DirectDrawFactory_CreateInstance, NULL},
  19. // add more entries here
  20. { NULL, NULL, NULL, NULL }
  21. };
  22. // static class factory (no allocs!)
  23. STDMETHODIMP CClassFactory_QueryInterface(IClassFactory *pcf, REFIID riid, void **ppvObj)
  24. {
  25. if (IsEqualIID(riid, &IID_IClassFactory) || IsEqualIID(riid, &IID_IUnknown))
  26. {
  27. *ppvObj = (void *)pcf;
  28. }
  29. else
  30. {
  31. *ppvObj = NULL;
  32. return E_NOINTERFACE;
  33. }
  34. DllAddRef();
  35. return NOERROR;
  36. }
  37. STDMETHODIMP_(ULONG) CClassFactory_AddRef(IClassFactory *pcf)
  38. {
  39. DllAddRef();
  40. return 2;
  41. }
  42. STDMETHODIMP_(ULONG) CClassFactory_Release(IClassFactory *pcf)
  43. {
  44. DllRelease();
  45. return 1;
  46. }
  47. STDMETHODIMP CClassFactory_CreateInstance(IClassFactory *pcf, IUnknown *punkOuter, REFIID riid, void **ppvObject)
  48. {
  49. OBJ_ENTRY *this = IToClass(OBJ_ENTRY, cf, pcf);
  50. return this->pfnCreate(punkOuter, riid, ppvObject);
  51. }
  52. STDMETHODIMP CClassFactory_LockServer(IClassFactory *pcf, BOOL fLock)
  53. {
  54. if (fLock)
  55. DllAddRef();
  56. else
  57. DllRelease();
  58. return S_OK;
  59. }
  60. const IClassFactoryVtbl c_CFVtbl = {
  61. CClassFactory_QueryInterface, CClassFactory_AddRef, CClassFactory_Release,
  62. CClassFactory_CreateInstance,
  63. CClassFactory_LockServer
  64. };
  65. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
  66. {
  67. if (IsEqualIID(riid, &IID_IClassFactory) || IsEqualIID(riid, &IID_IUnknown))
  68. {
  69. const OBJ_ENTRY *pcls;
  70. for (pcls = c_clsmap; pcls->pclsid; pcls++)
  71. {
  72. if (IsEqualIID(rclsid, pcls->pclsid))
  73. {
  74. *ppv = (void *)&(pcls->cf);
  75. DllAddRef(); // Class Factory keeps dll in memory
  76. return NOERROR;
  77. }
  78. }
  79. }
  80. // failure
  81. *ppv = NULL;
  82. return CLASS_E_CLASSNOTAVAILABLE;;
  83. }
  84. STDAPI_(void) DllAddRef()
  85. {
  86. InterlockedIncrement(&g_cRefDll);
  87. }
  88. STDAPI_(void) DllRelease()
  89. {
  90. InterlockedDecrement(&g_cRefDll);
  91. }
  92. STDAPI DllCanUnloadNow(void)
  93. {
  94. return g_cRefDll == 0 ? S_OK : S_FALSE;
  95. }
  96. STDAPI_(BOOL) DllEntryPoint(HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
  97. {
  98. if (dwReason == DLL_PROCESS_ATTACH)
  99. {
  100. g_hinst = hDll;
  101. DisableThreadLibraryCalls(hDll);
  102. }
  103. return TRUE;
  104. }
  105. STDAPI_(void) TStringFromGUID(const GUID* pguid, LPTSTR pszBuf)
  106. {
  107. wsprintf(pszBuf, TEXT("{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}"), pguid->Data1,
  108. pguid->Data2, pguid->Data3, pguid->Data4[0], pguid->Data4[1], pguid->Data4[2],
  109. pguid->Data4[3], pguid->Data4[4], pguid->Data4[5], pguid->Data4[6], pguid->Data4[7]);
  110. }
  111. #ifndef UNICODE
  112. STDAPI_(void) WStringFromGUID(const GUID* pguid, LPWSTR pszBuf)
  113. {
  114. char szAnsi[40];
  115. TStringFromGUID(pguid, szAnsi);
  116. MultiByteToWideChar(CP_ACP, 0, szAnsi, -1, pszBuf, sizeof(szAnsi));
  117. }
  118. #endif
  119. BOOL DeleteKeyAndSubKeys(HKEY hkIn, LPCTSTR pszSubKey)
  120. {
  121. HKEY hk;
  122. TCHAR szTmp[MAX_PATH];
  123. DWORD dwTmpSize;
  124. long l;
  125. BOOL f;
  126. l = RegOpenKeyEx(hkIn, pszSubKey, 0, KEY_ALL_ACCESS, &hk);
  127. if (l != ERROR_SUCCESS)
  128. return FALSE;
  129. // loop through all subkeys, blowing them away.
  130. //
  131. f = TRUE;
  132. while (f) {
  133. dwTmpSize = MAX_PATH;
  134. l = RegEnumKeyEx(hk, 0, szTmp, &dwTmpSize, 0, NULL, NULL, NULL);
  135. if (l != ERROR_SUCCESS)
  136. break;
  137. f = DeleteKeyAndSubKeys(hk, szTmp);
  138. }
  139. // there are no subkeys left, [or we'll just generate an error and return FALSE].
  140. // let's go blow this dude away.
  141. //
  142. RegCloseKey(hk);
  143. l = RegDeleteKey(hkIn, pszSubKey);
  144. return (l == ERROR_SUCCESS) ? TRUE : FALSE;
  145. }
  146. #define INPROCSERVER32 TEXT("InProcServer32")
  147. #define CLSID TEXT("CLSID")
  148. #define THREADINGMODEL TEXT("ThreadingModel")
  149. #define TMBOTH TEXT("Both")
  150. STDAPI DllRegisterServer(void)
  151. {
  152. const OBJ_ENTRY *pcls;
  153. TCHAR szPath[MAX_PATH];
  154. GetModuleFileName(g_hinst, szPath, ARRAYSIZE(szPath)); // get path to this DLL
  155. for (pcls = c_clsmap; pcls->pclsid; pcls++)
  156. {
  157. HKEY hkCLSID;
  158. if (RegOpenKey(HKEY_CLASSES_ROOT, CLSID, &hkCLSID) == ERROR_SUCCESS)
  159. {
  160. HKEY hkOurs;
  161. LONG err;
  162. TCHAR szGUID[80];
  163. TStringFromGUID(pcls->pclsid, szGUID);
  164. err = RegCreateKey(hkCLSID, szGUID, &hkOurs);
  165. if (err == ERROR_SUCCESS)
  166. {
  167. HKEY hkInproc;
  168. err = RegCreateKey(hkOurs, INPROCSERVER32, &hkInproc);
  169. if (err == ERROR_SUCCESS)
  170. {
  171. err = RegSetValueEx(hkInproc, NULL, 0, REG_SZ, (LPBYTE)szPath, (lstrlen(szPath) + 1) * sizeof(TCHAR));
  172. if (err == ERROR_SUCCESS)
  173. {
  174. err = RegSetValueEx(hkInproc, THREADINGMODEL, 0, REG_SZ, (LPBYTE)TMBOTH, sizeof(TMBOTH));
  175. }
  176. RegCloseKey(hkInproc);
  177. }
  178. if (pcls->pfnRegUnReg)
  179. pcls->pfnRegUnReg(TRUE, hkOurs, szGUID, szPath);
  180. RegCloseKey(hkOurs);
  181. }
  182. RegCloseKey(hkCLSID);
  183. if (err != ERROR_SUCCESS)
  184. return HRESULT_FROM_WIN32(err);
  185. }
  186. }
  187. return S_OK;
  188. }
  189. STDAPI DllUnregisterServer(void)
  190. {
  191. const OBJ_ENTRY *pcls;
  192. for (pcls = c_clsmap; pcls->pclsid; pcls++)
  193. {
  194. HKEY hkCLSID;
  195. if (RegOpenKey(HKEY_CLASSES_ROOT, CLSID, &hkCLSID) == ERROR_SUCCESS)
  196. {
  197. TCHAR szGUID[80];
  198. TStringFromGUID(pcls->pclsid, szGUID);
  199. DeleteKeyAndSubKeys(hkCLSID, szGUID);
  200. RegCloseKey(hkCLSID);
  201. if (pcls->pfnRegUnReg)
  202. pcls->pfnRegUnReg(FALSE, NULL, szGUID, NULL);
  203. }
  204. }
  205. return S_OK;
  206. }