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.

303 lines
7.3 KiB

  1. /*++
  2. Copyright (c) 1996-1997 Microsoft Corporation
  3. Module Name:
  4. oemcom.cxx
  5. Abstract:
  6. Implementation of Windows NT printer driver OEM COM plugins
  7. Environment:
  8. Windows NT
  9. Revision History:
  10. 02/06/98 -steveki-
  11. Initial framework.
  12. --*/
  13. #include <lib.h>
  14. #undef IUnknown
  15. #ifdef __cplusplus
  16. extern "C" {
  17. #endif
  18. static const CHAR szDllGetClassObject[] = "DllGetClassObject";
  19. static const CHAR szDllCanUnloadNow[] = "DllCanUnloadNow";
  20. #ifdef WINNT_40
  21. extern "C" EngFindImageProcAddress(HMODULE, CHAR *);
  22. extern "C" EngUnloadImage(HMODULE);
  23. #endif
  24. extern "C" HRESULT
  25. HDriver_CoGetClassObject(
  26. IN REFCLSID rclsid,
  27. IN DWORD dwClsContext,
  28. IN LPVOID pvReservedForDCOM,
  29. IN REFIID riid,
  30. IN LPVOID *ppv,
  31. IN HANDLE hInstance
  32. )
  33. /*++
  34. Routine Description:
  35. Locate and connect to the class factory object associated with the class identifier rclsid.
  36. Arguments:
  37. rclsid - Specifies the class factory component.
  38. dwClsContext - Specifies the context in which the executable code is to be run.
  39. pvReservedForDCOM - Reserved for future use; must be NULL.
  40. riid - Specifies the interface to be used to communicate with the class object.
  41. ppv - Points to where to return the pointer to the requested interface.
  42. hInstance - Handle to the loaded OEM plugin module.
  43. Return Value:
  44. S_OK if successful, E_FAIL if DllGetClassObject entry point is not found. Refer to COM spec
  45. for other possible error codes that can be returned.
  46. --*/
  47. {
  48. HRESULT hr = E_FAIL;
  49. LPFNGETCLASSOBJECT pfnDllGetClassObject = NULL;
  50. //
  51. // Get the class object procedure address.
  52. //
  53. if (hInstance && (pfnDllGetClassObject = (LPFNGETCLASSOBJECT)GetProcAddress((HMODULE)hInstance,
  54. (CHAR *)szDllGetClassObject)))
  55. {
  56. //
  57. // Ask for the class factory interface.
  58. //
  59. hr = pfnDllGetClassObject(rclsid, riid, ppv);
  60. }
  61. return hr;
  62. }
  63. extern "C" HRESULT
  64. HDriver_CoCreateInstance(
  65. IN REFCLSID rclsid,
  66. IN LPUNKNOWN pUnknownOuter,
  67. IN DWORD dwClsContext,
  68. IN REFIID riid,
  69. IN LPVOID *ppv,
  70. IN HANDLE hInstance
  71. )
  72. /*++
  73. Routine Description:
  74. Create an instance of the class rclsid, asking for interface riid using the given execution context.
  75. Arguments:
  76. rclsid - Specifies the class factory component.
  77. pUnknownOuter - Specifies the controlling unknown of the aggregate.
  78. dwClsContext - Specifies the context in which the executable is to be run.
  79. riid - Specifies the interface to be used to communicate with the class object.
  80. ppv - Points to where to return the pointer to the requested interface.
  81. hInstance - Handle to the loaded OEM plugin module.
  82. Return Value:
  83. S_OK if successful. Refer to COM spec for other possible error codes that can be returned.
  84. --*/
  85. {
  86. HRESULT hr = E_FAIL;
  87. IClassFactory *pIFactory = NULL;
  88. //
  89. // Set output parameter to NULL.
  90. //
  91. *ppv = NULL;
  92. //
  93. // We can only support in process servers. We do not have any
  94. // code for marshaling to another process.
  95. //
  96. if (dwClsContext == CLSCTX_INPROC_SERVER)
  97. {
  98. hr = HDriver_CoGetClassObject(rclsid,
  99. dwClsContext,
  100. NULL,
  101. IID_IClassFactory,
  102. (void **)&pIFactory,
  103. hInstance);
  104. if(SUCCEEDED(hr))
  105. {
  106. hr = pIFactory->CreateInstance(pUnknownOuter, riid, ppv);
  107. //
  108. // Release the class factory.
  109. //
  110. pIFactory->Release();
  111. }
  112. }
  113. else
  114. {
  115. hr = E_NOTIMPL;
  116. }
  117. return hr;
  118. }
  119. extern "C" VOID
  120. Driver_CoFreeOEMLibrary(
  121. IN HANDLE hInstance
  122. )
  123. /*++
  124. Routine Description:
  125. Unloads OEM plugin DLL that are no longer serving any components.
  126. Arguments:
  127. hInstance - Handle to the loaded OEM plugin module.
  128. Return Value:
  129. None.
  130. --*/
  131. {
  132. LPFNCANUNLOADNOW pfnDllCanUnloadNow = NULL;
  133. if (hInstance && (pfnDllCanUnloadNow = (LPFNCANUNLOADNOW)GetProcAddress((HMODULE)hInstance,
  134. (CHAR *)szDllCanUnloadNow)))
  135. {
  136. (VOID) pfnDllCanUnloadNow();
  137. //
  138. // We don't look at the return value of DllCanUnloadNow() and always do a FreeLibrary here,
  139. // otherwise we may end up with OEM DLL still remains in memory when all its instances are
  140. // unloaded.
  141. //
  142. // If OEM DLL spins off a working thread which also uses the OEM DLL, the thread needs to
  143. // do LoadLibrary and FreeLibraryExitThread, otherwise it may crash after we called FreeLibrary.
  144. //
  145. FreeLibrary((HMODULE)hInstance);
  146. }
  147. }
  148. extern "C" BOOL
  149. BQILatestOemInterface(
  150. IN HANDLE hInstance,
  151. IN REFCLSID rclsid,
  152. IN const GUID *PrintOem_IIDs[],
  153. OUT PVOID *ppIntfOem,
  154. OUT GUID *piidIntfOem
  155. )
  156. /*++
  157. Routine Description:
  158. Retrieve the latest interface supported by OEM plugin
  159. Arguments:
  160. hInstance - handle to the loaded OEM plugin module
  161. rclsid - specifies the class factory component
  162. PrintOem_IIDs[] - array of IIDs for plugin interfaces (from latest to oldest) driver supports
  163. ppIntfOem - points to where to return the interface pointer we get from OEM plugin
  164. piidIntfOem - points to where to return the IID for the interface we get from OEM plguin
  165. Return Value:
  166. TRUE if retrieving OEM plugin interface is successful. FALSE otherwise.
  167. --*/
  168. {
  169. IUnknown *pIUnknown = NULL;
  170. IUnknown *pIPrintOem = NULL;
  171. HRESULT hr;
  172. INT iid_index;
  173. BOOL bIntfFound;
  174. hr = HDriver_CoCreateInstance(rclsid,
  175. NULL,
  176. CLSCTX_INPROC_SERVER,
  177. IID_IUnknown,
  178. (void **)&pIUnknown,
  179. hInstance);
  180. if (FAILED(hr) || pIUnknown == NULL)
  181. {
  182. ERR(("HDriver_CoCreateInstance failed\n"));
  183. return FALSE;
  184. }
  185. iid_index = 0;
  186. bIntfFound = FALSE;
  187. //
  188. // QI for the driver supported plugin interfaces from latest to oldest,
  189. // until one is supported by the OEM plugin, or until we hit the NULL
  190. // terminator.
  191. //
  192. while (!bIntfFound && PrintOem_IIDs[iid_index] != NULL)
  193. {
  194. hr = pIUnknown->QueryInterface(*PrintOem_IIDs[iid_index], (void **)&pIPrintOem);
  195. if (SUCCEEDED(hr) && pIPrintOem != NULL)
  196. bIntfFound = TRUE;
  197. else
  198. iid_index++;
  199. }
  200. pIUnknown->Release();
  201. if (!bIntfFound)
  202. {
  203. ERR(("Can't get a plugin interface we support!\n"));
  204. return FALSE;
  205. }
  206. *ppIntfOem = (PVOID)pIPrintOem;
  207. *piidIntfOem = *PrintOem_IIDs[iid_index];
  208. return TRUE;
  209. }
  210. #ifdef __cplusplus
  211. }
  212. #endif