Source code of Windows XP (NT5)
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.

378 lines
8.6 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. prnevent.c
  5. Abstract:
  6. Implementation of DrvPrinterEvent
  7. Environment:
  8. Fax driver user interface
  9. Revision History:
  10. 05/10/96 -davidx-
  11. Created it.
  12. mm/dd/yy -author-
  13. description
  14. --*/
  15. #include "faxui.h"
  16. #include <gdispool.h>
  17. #include <winsprlp.h>
  18. typedef BOOL (WINAPI *PFAXPOINTPRINTINSTALL)(LPWSTR,LPWSTR);
  19. LPTSTR
  20. GetFaxServerDirectory(
  21. LPTSTR ServerName
  22. )
  23. /*++
  24. Routine Description:
  25. Find the directory containing the client setup software
  26. Arguments:
  27. pServerName - Specifies the name of the print/fax server
  28. Return Value:
  29. Pointer to name of the directory containing the client setup software
  30. NULL if there is an error
  31. --*/
  32. #define FAX_SHARE_NAME TEXT("\\Fax$\\")
  33. {
  34. LPTSTR Dir = MemAllocZ( SizeOfString(ServerName) + SizeOfString(FAX_SHARE_NAME) + 16 );
  35. if (Dir) {
  36. _tcscpy( Dir, ServerName );
  37. _tcscat( Dir, FAX_SHARE_NAME );
  38. }
  39. return Dir;
  40. }
  41. LPTSTR
  42. GetClientSetupDir(
  43. LPTSTR pServerName,
  44. LPTSTR pEnvironment
  45. )
  46. /*++
  47. Routine Description:
  48. Find the directory containing the client setup software
  49. Arguments:
  50. pServerName - Specifies the name of the print server
  51. pEnvironment - Specifies the client's machine architecture
  52. Return Value:
  53. Pointer to name of the directory containing the client setup software
  54. NULL if there is an error
  55. --*/
  56. #define DRIVERENV_I386 TEXT("Windows NT x86")
  57. #define DRIVERENV_ALPHA TEXT("Windows NT Alpha_AXP")
  58. #define ARCHSUFFIX_I386 TEXT("Clients\\i386\\")
  59. #define ARCHSUFFIX_ALPHA TEXT("Clients\\alpha\\")
  60. {
  61. LPTSTR pClientDir, pServerDir, pArchSuffix;
  62. //
  63. // Determine the client machine's architecture
  64. //
  65. pClientDir = pServerDir = pArchSuffix = NULL;
  66. if (pEnvironment != NULL) {
  67. if (_tcsicmp(pEnvironment, DRIVERENV_I386) == EQUAL_STRING)
  68. pArchSuffix = ARCHSUFFIX_I386;
  69. else if (_tcsicmp(pEnvironment, DRIVERENV_ALPHA) == EQUAL_STRING)
  70. pArchSuffix = ARCHSUFFIX_ALPHA;
  71. }
  72. if (pArchSuffix == NULL) {
  73. Error(("Bad driver envirnment: %ws\n", pEnvironment));
  74. SetLastError(ERROR_BAD_ENVIRONMENT);
  75. return NULL;
  76. }
  77. //
  78. // Get the server name and the driver directory on the server
  79. //
  80. if ((pServerName != NULL) &&
  81. (pServerDir = GetFaxServerDirectory(pServerName)) &&
  82. (pClientDir = MemAllocZ(SizeOfString(pServerDir) + SizeOfString(pArchSuffix))))
  83. {
  84. //
  85. // Copy the server driver directory string and truncate the last component
  86. //
  87. _tcscpy(pClientDir, pServerDir);
  88. _tcscat(pClientDir, pArchSuffix);
  89. Verbose(("Fax client setup directory: %ws\n", pClientDir));
  90. }
  91. MemFree(pServerDir);
  92. return pClientDir;
  93. }
  94. BOOL
  95. IsMetricCountry(
  96. VOID
  97. )
  98. /*++
  99. Routine Description:
  100. Determine if the current country is using metric system.
  101. Arguments:
  102. NONE
  103. Return Value:
  104. TRUE if the current country uses metric system, FALSE otherwise
  105. --*/
  106. {
  107. INT cch;
  108. PVOID pstr = NULL;
  109. LONG countryCode = CTRY_UNITED_STATES;
  110. //
  111. // Determine the size of the buffer needed to retrieve locale information.
  112. // Allocate the necessary space.
  113. //
  114. //
  115. if ((cch = GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_ICOUNTRY, NULL, 0)) > 0 &&
  116. (pstr = MemAlloc(sizeof(TCHAR) * cch)) &&
  117. (cch == GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_ICOUNTRY, pstr, cch)))
  118. {
  119. countryCode = _ttol(pstr);
  120. }
  121. MemFree(pstr);
  122. Verbose(("Default country code: %d\n", countryCode));
  123. //
  124. // This is the Win31 algorithm based on AT&T international dialing codes.
  125. //
  126. return ((countryCode == CTRY_UNITED_STATES) ||
  127. (countryCode == CTRY_CANADA) ||
  128. (countryCode >= 50 && countryCode < 60) ||
  129. (countryCode >= 500 && countryCode < 600)) ? FALSE : TRUE;
  130. }
  131. BOOL
  132. DrvPrinterEvent(
  133. LPWSTR pPrinterName,
  134. int DriverEvent,
  135. DWORD Flags,
  136. LPARAM lParam
  137. )
  138. /*++
  139. Routine Description:
  140. Implementation of DrvPrinterEvent entrypoint
  141. Arguments:
  142. pPrinterName - Specifies the name of the printer involved
  143. DriverEvent - Specifies what happened
  144. Flags - Specifies misc. flag bits
  145. lParam - Event specific parameters
  146. Return Value:
  147. TRUE if successful, FALSE otherwise
  148. --*/
  149. #define FaxClientSetupError(errMesg) { \
  150. Error(("%s failed: %d\n", errMesg, GetLastError())); \
  151. status = IDS_FAXCLIENT_SETUP_FAILED; \
  152. goto ExitDrvPrinterEvent; \
  153. }
  154. {
  155. HKEY hRegKey = NULL;
  156. HANDLE hPrinter = NULL;
  157. PDRIVER_INFO_2 pDriverInfo2 = NULL;
  158. PPRINTER_INFO_2 pPrinterInfo2 = NULL;
  159. HINSTANCE hInstFaxOcm = NULL;
  160. PFAXPOINTPRINTINSTALL FaxPointPrintInstall = NULL;
  161. LPTSTR pClientSetupDir = NULL;
  162. INT status = 0;
  163. TCHAR FaxOcmPath[MAX_PATH];
  164. TCHAR DestPath[MAX_PATH];
  165. Verbose(("DrvPrinterEvent: %d\n", DriverEvent));
  166. DestPath[0] = 0;
  167. //
  168. // Ignore any event other than Initialize and AddConnection
  169. //
  170. if (DriverEvent == PRINTER_EVENT_INITIALIZE) {
  171. static PRINTER_DEFAULTS printerDefault = {NULL, NULL, PRINTER_ALL_ACCESS};
  172. HANDLE hPrinter;
  173. if (OpenPrinter(pPrinterName, &hPrinter, &printerDefault)) {
  174. SetPrinterDataDWord(hPrinter, PRNDATA_ISMETRIC, IsMetricCountry());
  175. ClosePrinter(hPrinter);
  176. } else
  177. Error(("OpenPrinter failed: %d\n", GetLastError()));
  178. } else if (DriverEvent == PRINTER_EVENT_ADD_CONNECTION) {
  179. if (Flags & PRINTER_EVENT_FLAG_NO_UI)
  180. Error(("PRINTER_EVENT_FLAG_NO_UI set!\n"));
  181. //
  182. // Check if client installation was ever done before
  183. //
  184. if (! (hRegKey = GetUserInfoRegKey(REGKEY_FAX_USERINFO, REG_READWRITE))) {
  185. Error(("GetUserInfoRegKey failed: %d\n", GetLastError()));
  186. status = IDS_FAXCLIENT_SETUP_FAILED;
  187. } else if (! GetRegistryDword(hRegKey, REGVAL_FAXINSTALLED)) {
  188. if (! OpenPrinter(pPrinterName, &hPrinter, NULL) ||
  189. ! (pDriverInfo2 = MyGetPrinterDriver(hPrinter, 2)) ||
  190. ! (pPrinterInfo2 = MyGetPrinter(hPrinter, 2)))
  191. {
  192. FaxClientSetupError("OpenPrinter");
  193. }
  194. //
  195. // Locate faxocm.dll and load it into memory
  196. //
  197. if (!(pClientSetupDir = GetClientSetupDir(pPrinterInfo2->pServerName,pDriverInfo2->pEnvironment))) {
  198. FaxClientSetupError("GetClientSetupDir");
  199. }
  200. _tcscpy( FaxOcmPath, pClientSetupDir );
  201. _tcscat( FaxOcmPath, TEXT("faxocm.dll") );
  202. GetTempPath( sizeof(DestPath)/sizeof(TCHAR), DestPath );
  203. if (DestPath[_tcslen(DestPath)-1] != TEXT('\\')) {
  204. _tcscat( DestPath, TEXT("\\") );
  205. }
  206. _tcscat( DestPath, TEXT("faxocm.dll") );
  207. if (!CopyFile( FaxOcmPath, DestPath, FALSE )) {
  208. FaxClientSetupError("CopyFile");
  209. }
  210. if (!(hInstFaxOcm = LoadLibrary(DestPath))) {
  211. FaxClientSetupError("LoadLibrary");
  212. }
  213. FaxPointPrintInstall = (PFAXPOINTPRINTINSTALL) GetProcAddress(hInstFaxOcm, "FaxPointPrintInstall");
  214. if (FaxPointPrintInstall == NULL) {
  215. FaxClientSetupError("GetProcAddress");
  216. }
  217. //
  218. // Find the directory containing the client setup software
  219. // and then run the install procedure in faxocm.dll
  220. //
  221. if (!FaxPointPrintInstall(pClientSetupDir, pPrinterName))
  222. {
  223. FaxClientSetupError("GetClientSetupDir");
  224. } else {
  225. //
  226. // Indicate the client setup has been run
  227. //
  228. SetRegistryDword(hRegKey, REGVAL_FAXINSTALLED, 1);
  229. }
  230. }
  231. ExitDrvPrinterEvent:
  232. //
  233. // Cleanup properly before returning
  234. //
  235. if (status != 0) {
  236. DeletePrinterConnection(pPrinterName);
  237. DisplayMessageDialog(NULL, 0, 0, status);
  238. }
  239. MemFree(pClientSetupDir);
  240. MemFree(pDriverInfo2);
  241. MemFree(pPrinterInfo2);
  242. if (hInstFaxOcm)
  243. FreeLibrary(hInstFaxOcm);
  244. if (hPrinter)
  245. ClosePrinter(hPrinter);
  246. if (hRegKey)
  247. RegCloseKey(hRegKey);
  248. if (DestPath[0])
  249. DeleteFile( DestPath );
  250. }
  251. return TRUE;
  252. }