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.

603 lines
18 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. psndsdb.c
  5. Abstract:
  6. Read the Print Configuration Attributes
  7. $Log: N:\NT\PRIVATE\NW4\NWSCRIPT\VCS\PS40DB.C $
  8. *
  9. * Rev 1.4 10 Apr 1996 14:23:28 terryt
  10. * Hotfix for 21181hq
  11. *
  12. * Rev 1.4 12 Mar 1996 19:55:22 terryt
  13. * Relative NDS names and merge
  14. *
  15. * Rev 1.3 04 Jan 1996 18:57:36 terryt
  16. * Bug fixes reported by MS
  17. *
  18. * Rev 1.2 22 Dec 1995 14:26:22 terryt
  19. * Add Microsoft headers
  20. *
  21. * Rev 1.1 20 Nov 1995 15:09:46 terryt
  22. * Context and capture changes
  23. *
  24. * Rev 1.0 15 Nov 1995 18:07:52 terryt
  25. * Initial revision.
  26. --*/
  27. #include "common.h"
  28. extern DWORD SwapLong(DWORD number);
  29. extern char *TYPED_USER_NAME;
  30. unsigned int
  31. PS40GetJobName(
  32. unsigned int NDSCaptureFlag,
  33. unsigned short SearchFlag,
  34. unsigned char *pOwner,
  35. unsigned char *pJobName,
  36. PPS_JOB_RECORD pJobRecord,
  37. unsigned char GetDefault
  38. );
  39. #include <pshpack1.h>
  40. #define NWPS_JOB_NAME_SIZE 32 /* 31 bytes and a '\0' */
  41. #define NWPS_FORM_NAME_SIZE 12 /* 12 bytes and a '\0' */
  42. #define NWPS_BANNER_NAME_SIZE 12 /* 12 bytes and a '\0' */
  43. #define NWPS_BANNER_FILE_SIZE 12 /* 12 bytes and a '\0' */
  44. #define NWPS_DEVI_NAME_SIZE 32 /* 32 bytes and a '\0' */
  45. #define NWPS_MODE_NAME_SIZE 32 /* 32 bytes and a '\0' */
  46. #define NWPS_BIND_NAME_SIZE 48
  47. #define NWPS_MAX_NAME_SIZE 514
  48. /*
  49. // NWPS_Job_Old_Db_Hdr is the first record in the 4.0 PrnConDB database.
  50. // It contains the following information about the database:
  51. // The version number,
  52. // the number of NWPS_Job_Rec records in PrnConDB,
  53. // the name of the default print job configuration and
  54. // the name of the job record owner.
  55. */
  56. typedef struct {
  57. char text[ 76 ]; /* Printcon database. Version 4.0 */
  58. char DefaultJobName[ 32 ]; /* Name of default Job */
  59. char Owner[ 256 ]; /* owner of the job record */
  60. WORD NumberOfRecords; /* # of NWPS_Job_Rec's in PrnConDB */
  61. WORD NumberOfBlocks; /* # of 50-(NWPS_Job_Name_Rec) blocks */
  62. BYTE MajorVersion; /* 4 */
  63. BYTE MinorVersion; /* 0 */
  64. } PRINTCON_40_HEADER;
  65. #define PRINTCON_40_HEADER_SIZE sizeof(PRINTCON_40_HEADER)
  66. /*
  67. // NWPS_Job_41_Db_Hdr is the first record in the 4.1 PrnConDB database.
  68. // It contains the following information about the database:
  69. // The version number,
  70. // the number of NWPS_Job_Rec records in PrnConDB,
  71. // the name of the default print job configuration and
  72. // the name of the job record owner IN UNICODE.
  73. */
  74. typedef struct {
  75. char text[ 76 ]; /* Printcon database. Version 4.1 */
  76. char DefaultJobName[ 32 ]; /* Name of default Job */
  77. char unused[ 256 ]; /* no longer used. */
  78. WORD NumberOfRecords; /* # of NWPS_Job_Rec's in PrnConDB */
  79. WORD NumberOfBlocks; /* # of 50-(NWPS_Job_Name_Rec) blocks */
  80. BYTE MajorVersion; /* 4 */
  81. BYTE MinorVersion; /* 1 unicode defaultPJOwner etc. */
  82. WORD Owner[ 256 ]; /* owner of the default job record */
  83. } PRINTCON_41_HEADER;
  84. #define PRINTCON_41_HEADER_SIZE sizeof(PRINTCON_41_HEADER)
  85. /*
  86. // NWPS_Job_Name_Rec is the type of record found in the
  87. // second section of the PrnConDB database. Each one of
  88. // these records contains the name of each NWPS_Job_Rec
  89. // and a pointer to their location in the third section of
  90. // the database. There is space set aside in this second
  91. // section for fifty NWPS_Job_Name_Rec records; if this
  92. // limit is exceeded then another fifty-record block following
  93. // the first one is allocated after the third section of the
  94. // database is moved down to make room for the expansion.
  95. */
  96. typedef struct {
  97. char JobName[ NWPS_JOB_NAME_SIZE ]; /* 1 - 31 chars long + 0 */
  98. long JobRecordOffset; /* Offset of the record
  99. // (from the beginning
  100. // of the 3rd section for 4.0
  101. // databases and from the start
  102. // of the file for pre-4.0)
  103. */
  104. } JOB_NAME_AREA;
  105. #define JOB_NAME_AREA_SIZE sizeof(JOB_NAME_AREA)
  106. typedef struct {
  107. union {
  108. struct {
  109. DWORD DataType : 1; /* 0=Byte stream 1 = Text */
  110. DWORD FormFeed : 1; /* 0 = FF; 1 = suppress FF */
  111. DWORD NotifyWhenDone : 1; /* 0 = no, 1 = yes */
  112. DWORD BannerFlag : 1; /* 0 = no, 1 = yes */
  113. DWORD AutoEndCap : 1; /* 0 = no, 1 = yes */
  114. DWORD TimeOutFlag: 1; /* 0 = no, 1 = yes */
  115. DWORD SystemType : 3; /* 0 = bindery 1 = NDS */
  116. DWORD Destination: 3; /* 0 = queue 1 = printer */
  117. DWORD unknown : 20;
  118. };
  119. DWORD PrintJobFlags;
  120. };
  121. WORD NumberOfCopies; /* 1 - 65,000 */
  122. WORD TimeoutCount; /* 1 - 1,000 */
  123. BYTE TabSize; /* 1 - 18 */
  124. BYTE LocalPrinter; /* 0=Lpt1, 1=Lpt2, 2=Lpt3 etc. */
  125. char FormName[ NWPS_FORM_NAME_SIZE + 2 ]; /* 1-12 chars */
  126. char Name[ NWPS_BANNER_NAME_SIZE + 2 ]; /* 1-12 chars */
  127. char BannerName[ NWPS_BANNER_FILE_SIZE + 2 ]; /* 1-12 chars */
  128. char Device[ NWPS_DEVI_NAME_SIZE + 2 ]; /* 1-32 chars */
  129. char Mode[ NWPS_MODE_NAME_SIZE + 2 ]; /* 1-32 chars */
  130. union {
  131. struct {
  132. /* pad structures on even boundries */
  133. char Server[ NWPS_BIND_NAME_SIZE + 2 ]; /* 2-48 chars */
  134. char QueueName[ NWPS_BIND_NAME_SIZE + 2 ]; /* 1-48 chars */
  135. char PrintServer[ NWPS_BIND_NAME_SIZE + 2 ]; /* 1-48 chars */
  136. } NonDS;
  137. char DSObjectName[ NWPS_MAX_NAME_SIZE ];
  138. } u;
  139. BYTE reserved[390]; /* Adds up to 1024 total (was 1026) */
  140. } JOB_RECORD_AREA;
  141. #define JOB_RECORD_AREA_SIZE sizeof(JOB_RECORD_AREA)
  142. #include <poppack.h>
  143. /*++
  144. *******************************************************************
  145. PS40JobGetDefault
  146. Routine Description:
  147. Get the default print job configuration from 40.
  148. Arguments:
  149. NDSCaptureFlag
  150. SearchFlag =
  151. pOwner =
  152. pJobName = A pointer to return the default job configuration name.
  153. pJobRecord = A pointer to return the default job configuration.
  154. Return Value:
  155. SUCCESSFUL 0x0000
  156. PS_ERR_BAD_VERSION 0x7770
  157. PS_ERR_GETTING_DEFAULT 0x7773
  158. PS_ERR_OPENING_DB 0x7774
  159. PS_ERR_READING_DB 0x7775
  160. PS_ERR_READING_RECORD 0x7776
  161. PS_ERR_INTERNAL_ERROR 0x7779
  162. PS_ERR_NO_DEFAULT_SPECIFIED 0x777B
  163. INVALID_CONNECTION 0x8801
  164. *******************************************************************
  165. --*/
  166. unsigned int
  167. PS40JobGetDefault(
  168. unsigned int NDSCaptureFlag,
  169. unsigned short SearchFlag,
  170. unsigned char *pOwner,
  171. unsigned char *pJobName,
  172. PPS_JOB_RECORD pJobRecord
  173. )
  174. {
  175. return PS40GetJobName(
  176. NDSCaptureFlag,
  177. SearchFlag,
  178. pOwner,
  179. pJobName,
  180. pJobRecord,
  181. TRUE);
  182. }
  183. /*++
  184. *******************************************************************
  185. PS40JobRead
  186. Routine Description:
  187. Get the print job configuration from 40.
  188. Arguments:
  189. NDSCaptureFlag =
  190. pOwner =
  191. pJobName = A pointer to return the default job configuration name.
  192. pJobRecord = A pointer to return the default job configuration.
  193. Return Value:
  194. SUCCESSFUL 0x0000
  195. PS_ERR_BAD_VERSION 0x7770
  196. PS_ERR_GETTING_DEFAULT 0x7773
  197. PS_ERR_OPENING_DB 0x7774
  198. PS_ERR_READING_DB 0x7775
  199. PS_ERR_READING_RECORD 0x7776
  200. PS_ERR_INTERNAL_ERROR 0x7779
  201. PS_ERR_NO_DEFAULT_SPECIFIED 0x777B
  202. INVALID_CONNECTION 0x8801
  203. *******************************************************************
  204. --*/
  205. unsigned int
  206. PS40JobRead(
  207. unsigned int NDSCaptureFlag,
  208. unsigned char *pOwner,
  209. unsigned char *pJobName,
  210. PPS_JOB_RECORD pJobRecord
  211. )
  212. {
  213. return PS40GetJobName(
  214. NDSCaptureFlag,
  215. 0,
  216. pOwner,
  217. pJobName,
  218. pJobRecord,
  219. FALSE);
  220. }
  221. /*++
  222. *******************************************************************
  223. PS40GetJobName
  224. Routine Description:
  225. Common routine to get the print job configuration from 40.
  226. Arguments:
  227. NDSCaptureFlag =
  228. SearchFlag =
  229. pOwner =
  230. pJobName = A pointer to return the default job configuration name.
  231. pJobRecord = A pointer to return the default job configuration.
  232. GetDefault = TRUE = get the default job name, FALSE = Don't get
  233. the default job name.
  234. Return Value:
  235. SUCCESSFUL 0x0000
  236. PS_ERR_BAD_VERSION 0x7770
  237. PS_ERR_GETTING_DEFAULT 0x7773
  238. PS_ERR_OPENING_DB 0x7774
  239. PS_ERR_READING_DB 0x7775
  240. PS_ERR_READING_RECORD 0x7776
  241. PS_ERR_INTERNAL_ERROR 0x7779
  242. PS_ERR_NO_DEFAULT_SPECIFIED 0x777B
  243. INVALID_CONNECTION 0x8801
  244. *******************************************************************
  245. --*/
  246. unsigned int
  247. PS40GetJobName(
  248. unsigned int NDSCaptureFlag,
  249. unsigned short SearchFlag,
  250. unsigned char *pOwner,
  251. unsigned char *pJobName,
  252. PPS_JOB_RECORD pJobRecord,
  253. unsigned char GetDefault
  254. )
  255. {
  256. unsigned char *pSearchJobName;
  257. unsigned long ObjectId;
  258. HANDLE stream = NULL;
  259. unsigned int Count;
  260. unsigned int Bytes;
  261. unsigned int RetCode = 0;
  262. unsigned int ConnectionNumber;
  263. JOB_NAME_AREA JobNameArea;
  264. JOB_RECORD_AREA JobRecord;
  265. PRINTCON_40_HEADER PrintConHeader;
  266. unsigned int Version40 = FALSE;
  267. unsigned int ConnectionHandle;
  268. unsigned char MailDirPath[NCP_MAX_PATH_LENGTH];
  269. unsigned char TempJobName[33];
  270. PBYTE JobContext = NULL;
  271. unsigned FileSize;
  272. // TRACKING Printer names can be used instead of queues
  273. // Must lookup "default print queue" if NT doesn't
  274. if ( NDSCaptureFlag ) {
  275. if ( !GetDefault ) {
  276. JobContext = strchr( pJobName, ':' );
  277. if ( JobContext ) {
  278. *JobContext = '\0';
  279. strncpy( TempJobName, pJobName, 32 );
  280. TempJobName[32] = 0;
  281. *JobContext++ = ':';
  282. pJobName = TempJobName;
  283. }
  284. }
  285. if ( JobContext ) {
  286. if (NDSfopenStream ( JobContext, "Print Job Configuration", &stream,
  287. &FileSize )) {
  288. RetCode = PS_ERR_OPENING_DB;
  289. goto CommonExit;
  290. }
  291. }
  292. else {
  293. if (NDSfopenStream ( TYPED_USER_NAME, "Print Job Configuration",
  294. &stream, &FileSize)) {
  295. PBYTE p;
  296. for ( p = TYPED_USER_NAME; p ; p = strchr ( p, '.' ) )
  297. {
  298. p++;
  299. if ( *p == 'O' && *(p+1) == 'U' && *(p+2) == '=' )
  300. break;
  301. if ( *p == 'O' && *(p+1) == '=' )
  302. break;
  303. }
  304. if (NDSfopenStream ( p, "Print Job Configuration", &stream,
  305. &FileSize)) {
  306. RetCode = PS_ERR_OPENING_DB;
  307. goto CommonExit;
  308. }
  309. }
  310. }
  311. }
  312. else {
  313. if (!CGetDefaultConnectionID (&ConnectionHandle)) {
  314. RetCode = PS_ERR_OPENING_DB;
  315. goto CommonExit;
  316. }
  317. RetCode = GetConnectionNumber(ConnectionHandle, &ConnectionNumber);
  318. if (RetCode) {
  319. goto CommonExit;
  320. }
  321. RetCode = GetBinderyObjectID (ConnectionHandle, LOGIN_NAME,
  322. OT_USER, &ObjectId);
  323. if (RetCode) {
  324. goto CommonExit;
  325. }
  326. /** Build the path to open the file **/
  327. sprintf(MailDirPath, "SYS:MAIL/%lX/PRINTJOB.DAT", SwapLong(ObjectId));
  328. stream = CreateFileA( NTNWtoUNCFormat( MailDirPath ),
  329. GENERIC_READ,
  330. FILE_SHARE_READ,
  331. NULL,
  332. OPEN_EXISTING,
  333. FILE_ATTRIBUTE_NORMAL,
  334. NULL );
  335. if (stream == INVALID_HANDLE_VALUE) {
  336. sprintf(MailDirPath, "SYS:PUBLIC/PRINTJOB.DAT");
  337. stream = CreateFileA( NTNWtoUNCFormat(MailDirPath),
  338. GENERIC_READ,
  339. FILE_SHARE_READ,
  340. NULL,
  341. OPEN_EXISTING,
  342. FILE_ATTRIBUTE_NORMAL,
  343. NULL );
  344. if (stream == INVALID_HANDLE_VALUE) {
  345. RetCode = PS_ERR_OPENING_DB;
  346. goto CommonExit;
  347. }
  348. }
  349. }
  350. if ( !ReadFile( stream, (PBYTE) &PrintConHeader, PRINTCON_40_HEADER_SIZE, &Bytes, NULL ) ) {
  351. RetCode = PS_ERR_INTERNAL_ERROR;
  352. goto CommonExit;
  353. }
  354. if (Bytes < PRINTCON_40_HEADER_SIZE) {
  355. if ( !( NDSCaptureFlag && Bytes) ) {
  356. RetCode = PS_ERR_INTERNAL_ERROR;
  357. goto CommonExit;
  358. }
  359. }
  360. /** Check the version number **/
  361. if ( PrintConHeader.MajorVersion != 4 ) {
  362. RetCode = PS_ERR_BAD_VERSION;
  363. goto CommonExit;
  364. }
  365. if ( PrintConHeader.MinorVersion == 0 ) {
  366. Version40 = TRUE;
  367. }
  368. /** Get the name we are looking for **/
  369. if (GetDefault) {
  370. if (PrintConHeader.DefaultJobName[0] == 0) {
  371. RetCode = PS_ERR_GETTING_DEFAULT;
  372. goto CommonExit;
  373. }
  374. pSearchJobName = PrintConHeader.DefaultJobName;
  375. }
  376. else {
  377. pSearchJobName = pJobName;
  378. }
  379. if ( !Version40 ) {
  380. SetFilePointer( stream, PRINTCON_41_HEADER_SIZE, NULL, FILE_BEGIN );
  381. }
  382. Count = 0;
  383. /** Go through all of the job entry to look for the name **/
  384. while (Count < PrintConHeader.NumberOfRecords) {
  385. if ( !ReadFile( stream, (PBYTE) &JobNameArea, JOB_NAME_AREA_SIZE, &Bytes, NULL) ) {
  386. RetCode = PS_ERR_INTERNAL_ERROR;
  387. goto CommonExit;
  388. }
  389. if (Bytes < JOB_NAME_AREA_SIZE) {
  390. if ( !( NDSCaptureFlag && Bytes) ) {
  391. RetCode = PS_ERR_INTERNAL_ERROR;
  392. goto CommonExit;
  393. }
  394. }
  395. Count++;
  396. /** Skip the entry with a null job name **/
  397. if (JobNameArea.JobName[0] == 0) {
  398. continue;
  399. }
  400. /** Is this the job name we are looking for? **/
  401. if (!_strcmpi(pSearchJobName, JobNameArea.JobName)) {
  402. break;
  403. }
  404. }
  405. /** See if we found the job name **/
  406. if (Count > PrintConHeader.NumberOfRecords) {
  407. if (GetDefault) {
  408. RetCode = PS_ERR_GETTING_DEFAULT;
  409. }
  410. else {
  411. RetCode = PS_ERR_READING_RECORD;
  412. }
  413. goto CommonExit;
  414. }
  415. /*
  416. * The Job offset starts at the beginning of the third section.
  417. * The third section starts after the Header and after the
  418. * 50 record blocks.
  419. */
  420. if ( Version40 ) {
  421. SetFilePointer( stream,
  422. PRINTCON_40_HEADER_SIZE +
  423. ( PrintConHeader.NumberOfBlocks * 50) * JOB_NAME_AREA_SIZE +
  424. JobNameArea.JobRecordOffset,
  425. NULL,
  426. FILE_BEGIN );
  427. }
  428. else {
  429. SetFilePointer( stream,
  430. PRINTCON_41_HEADER_SIZE +
  431. ( PrintConHeader.NumberOfBlocks * 50) * JOB_NAME_AREA_SIZE +
  432. JobNameArea.JobRecordOffset,
  433. NULL,
  434. FILE_BEGIN );
  435. }
  436. memset((PBYTE)&JobRecord, 0, sizeof(JobRecord));
  437. if ( !ReadFile( stream, (PBYTE) &JobRecord, JOB_RECORD_AREA_SIZE, &Bytes, NULL) ) {
  438. RetCode = PS_ERR_READING_RECORD;
  439. goto CommonExit;
  440. }
  441. if (Bytes < JOB_RECORD_AREA_SIZE) {
  442. if ( !( NDSCaptureFlag && Bytes) ) {
  443. RetCode = PS_ERR_READING_RECORD;
  444. goto CommonExit;
  445. }
  446. }
  447. memset(pJobRecord, 0, PS_JOB_RECORD_SIZE);
  448. if (JobRecord.NotifyWhenDone) {
  449. pJobRecord->PrintJobFlag |= PS_JOB_NOTIFY;
  450. }
  451. if (JobRecord.BannerFlag) {
  452. pJobRecord->PrintJobFlag |= PS_JOB_PRINT_BANNER;
  453. }
  454. if (JobRecord.DataType) {
  455. pJobRecord->PrintJobFlag |= PS_JOB_EXPAND_TABS;
  456. }
  457. if (JobRecord.FormFeed) {
  458. pJobRecord->PrintJobFlag |= PS_JOB_NO_FORMFEED;
  459. }
  460. if (JobRecord.AutoEndCap) {
  461. pJobRecord->PrintJobFlag |= PS_JOB_AUTO_END;
  462. }
  463. if (JobRecord.TimeoutCount) {
  464. pJobRecord->PrintJobFlag |= PS_JOB_TIMEOUT;
  465. }
  466. if (JobRecord.Destination) {
  467. pJobRecord->PrintJobFlag |= PS_JOB_DS_PRINTER;
  468. }
  469. if ( JobRecord.SystemType ) {
  470. pJobRecord->PrintJobFlag |= PS_JOB_ENV_DS;
  471. }
  472. pJobRecord->Copies = JobRecord.NumberOfCopies;
  473. pJobRecord->TabSize = JobRecord.TabSize;
  474. pJobRecord->TimeOutCount = JobRecord.TimeoutCount;
  475. pJobRecord->LocalPrinter = JobRecord.LocalPrinter;
  476. strcpy(pJobRecord->Mode, JobRecord.Mode);
  477. strcpy(pJobRecord->Device, JobRecord.Device);
  478. strcpy(pJobRecord->FormName, JobRecord.FormName);
  479. strcpy(pJobRecord->BannerName, JobRecord.BannerName);
  480. if ( JobRecord.SystemType ) {
  481. ConvertUnicodeToAscii( JobRecord.u.DSObjectName );
  482. strcpy(pJobRecord->u.DSObjectName, JobRecord.u.DSObjectName);
  483. }
  484. else {
  485. strcpy(pJobRecord->u.NonDS.PrintQueue, JobRecord.u.NonDS.QueueName);
  486. strcpy(pJobRecord->u.NonDS.FileServer, JobRecord.u.NonDS.Server);
  487. }
  488. if (GetDefault && pJobName) {
  489. strcpy(pJobName, JobNameArea.JobName);
  490. }
  491. if (pOwner) {
  492. *pOwner = 0;
  493. }
  494. CommonExit:
  495. if (stream != NULL) {
  496. // 07/19/96 cjc (Citrix code merge)
  497. // fclose causes a trap cause it expects *stream but
  498. // really should be using CloseHandle anyway.
  499. CloseHandle( stream );
  500. // if ( NDSCaptureFlag )
  501. // CloseHandle( stream );
  502. // else
  503. // fclose( stream );
  504. }
  505. return RetCode;
  506. }