1 | #define INCL_DEV
|
---|
2 | #define INCL_DOSERRORS
|
---|
3 | #define INCL_DOSMISC
|
---|
4 | #define INCL_DOSPROFILE
|
---|
5 | #define INCL_SPL
|
---|
6 | #define INCL_SPLDOSPRINT
|
---|
7 | #define INCL_SPLERRORS
|
---|
8 | #define INCL_PM
|
---|
9 | #define INCL_WIN
|
---|
10 | #ifndef OS2_INCLUDED
|
---|
11 | #include <os2.h>
|
---|
12 | #endif
|
---|
13 | #include <ctype.h>
|
---|
14 | #include <stdio.h>
|
---|
15 | #include <stdlib.h>
|
---|
16 | #include <string.h>
|
---|
17 |
|
---|
18 |
|
---|
19 | // CONSTANTS
|
---|
20 |
|
---|
21 | #define APPNAME_PM_PRINT_OBJECT "PM_PrintObject"
|
---|
22 | #define APPNAME_PM_ABS_OBJECTS "PM_Abstract:Objects"
|
---|
23 | #define APPNAME_PM_WPS_LOCATION "PM_Workplace:Location"
|
---|
24 |
|
---|
25 | #define ID_OBJINFO_QUEUENAME 3
|
---|
26 | #define ID_OBJINFO_RPQUEUENAME 13
|
---|
27 |
|
---|
28 |
|
---|
29 | // DATA TYPES
|
---|
30 |
|
---|
31 | /* Structures needed used to parse PM_Abstract:Object data
|
---|
32 | */
|
---|
33 | #pragma pack(1)
|
---|
34 | typedef struct _Object_Info
|
---|
35 | {
|
---|
36 | USHORT cbName; // Size of szName, including terminator
|
---|
37 | USHORT cbData; // Number of additional data bytes following szName
|
---|
38 | CHAR szName[1]; // Name of object type
|
---|
39 | } OBJINFO, *POBJINFO;
|
---|
40 |
|
---|
41 | typedef struct _Object_Tag_Info
|
---|
42 | {
|
---|
43 | USHORT usTagFormat; // Tag data format
|
---|
44 | USHORT usTag; // Tag ID
|
---|
45 | USHORT cbTag; // Size of tag data
|
---|
46 | } OITAG, *POITAG;
|
---|
47 | #pragma pack()
|
---|
48 |
|
---|
49 |
|
---|
50 | /* ------------------------------------------------------------------------- *
|
---|
51 | * PrinterObjectHandle *
|
---|
52 | * *
|
---|
53 | * Given a print queue name, obtain the handle to the WPS printer object *
|
---|
54 | * associated with that queue. This is done by querying OS2.INI for the *
|
---|
55 | * queues defined in PM_PrintObject and reading the associated handle IDs. *
|
---|
56 | * *
|
---|
57 | * ARGUMENTS: *
|
---|
58 | * PSZ pszQueueName: The printer queue name. This is NOT the same as the *
|
---|
59 | * printer device name, although in many cases they may *
|
---|
60 | * have the same value. *
|
---|
61 | * *
|
---|
62 | * RETURNS: HOBJECT *
|
---|
63 | * WPS object handle of the printer object; NULLHANDLE if no object was *
|
---|
64 | * found or an error occurred. *
|
---|
65 | * ------------------------------------------------------------------------- */
|
---|
66 | HOBJECT PrinterObjectHandle( PSZ pszQueueName )
|
---|
67 | {
|
---|
68 | PVOID pbuf = NULL,
|
---|
69 | pdata = NULL;
|
---|
70 | PBYTE pb,
|
---|
71 | pbEnd,
|
---|
72 | pbGrpEnd;
|
---|
73 | POBJINFO pInfo = NULL;
|
---|
74 | POITAG pTag = NULL;
|
---|
75 | PSZ psz,
|
---|
76 | pszName;
|
---|
77 | CHAR szValue[ 256 ],
|
---|
78 | szObject[ 5 ];
|
---|
79 | ULONG cbTotal = 0,
|
---|
80 | cbActual = 0,
|
---|
81 | ulHandle;
|
---|
82 | HOBJECT hObj = 0;
|
---|
83 | BOOL fFound,
|
---|
84 | fRC;
|
---|
85 |
|
---|
86 |
|
---|
87 | fRC = PrfQueryProfileSize( HINI_USERPROFILE,
|
---|
88 | APPNAME_PM_PRINT_OBJECT, NULL, &cbTotal );
|
---|
89 | if ( !fRC || !cbTotal ) {
|
---|
90 | return NULLHANDLE;
|
---|
91 | }
|
---|
92 | pbuf = malloc( cbTotal );
|
---|
93 | if ( !pbuf ) {
|
---|
94 | return NULLHANDLE;
|
---|
95 | }
|
---|
96 |
|
---|
97 | cbActual = PrfQueryProfileString( HINI_USERPROFILE, APPNAME_PM_PRINT_OBJECT,
|
---|
98 | NULL, NULL, pbuf, cbTotal );
|
---|
99 | if ( !cbActual ) {
|
---|
100 | return NULLHANDLE;
|
---|
101 | }
|
---|
102 |
|
---|
103 | fFound = FALSE;
|
---|
104 | psz = (PSZ) pbuf;
|
---|
105 | while ( *psz && !fFound ) {
|
---|
106 |
|
---|
107 | // --
|
---|
108 | if ( sscanf( psz, "%u", &ulHandle ) && LOUSHORT( ulHandle )) {
|
---|
109 | printf("Checking printer object %X\n", ulHandle );
|
---|
110 | sprintf( szObject, "%X", LOUSHORT( ulHandle ));
|
---|
111 | fRC = PrfQueryProfileSize( HINI_USERPROFILE, APPNAME_PM_ABS_OBJECTS,
|
---|
112 | szObject, &cbTotal );
|
---|
113 | if ( !fRC || ( cbTotal < 25 ) || ((pdata = malloc( cbTotal )) == NULL )) {
|
---|
114 | psz += strlen( psz ) + 1;
|
---|
115 | continue;
|
---|
116 | }
|
---|
117 | if ( PrfQueryProfileData( HINI_USERPROFILE, APPNAME_PM_ABS_OBJECTS,
|
---|
118 | szObject, (PVOID) pdata, &cbTotal ))
|
---|
119 | {
|
---|
120 | BOOL fRemote;
|
---|
121 | pbEnd = (PBYTE) pdata + cbTotal;
|
---|
122 | pszName = (PSZ) pdata + sizeof( ULONG );
|
---|
123 | fRemote = strcmp( pszName, "WPRPrinter") ? FALSE : TRUE;
|
---|
124 | pb = (PBYTE) pszName + strlen( pszName ) + 17;
|
---|
125 | while (( pb < pbEnd ) && !fFound ) {
|
---|
126 | pInfo = (POBJINFO) pb;
|
---|
127 | pb += sizeof( OBJINFO ) + strlen( pInfo->szName );
|
---|
128 | pbGrpEnd = pb + pInfo->cbData;
|
---|
129 | if ( pbGrpEnd > pbEnd ) pbGrpEnd = pbEnd;
|
---|
130 | while (( pb < pbGrpEnd ) && !fFound ) {
|
---|
131 | pTag = (POITAG) pb;
|
---|
132 | pb += sizeof( OITAG );
|
---|
133 | //printf(" - checking tag: %x\n", pTag->usTag );
|
---|
134 | /* For network printers, tag ID 3 indicates the name of
|
---|
135 | * the queue on the remote server. We want the local
|
---|
136 | * queue name, which has tag ID 13.
|
---|
137 | */
|
---|
138 | if ( fRemote && ( pTag->usTag == ID_OBJINFO_RPQUEUENAME )) {
|
---|
139 | memcpy( szValue, pb, pTag->cbTag );
|
---|
140 | if ( !strcmp( szValue, pszQueueName )) {
|
---|
141 | printf("Found queue %s\n", szValue );
|
---|
142 | hObj = (HOBJECT) ulHandle;
|
---|
143 | fFound = TRUE;
|
---|
144 | }
|
---|
145 | }
|
---|
146 | // For local printers, just look for tag ID 3
|
---|
147 | else if ( pTag->usTag == ID_OBJINFO_QUEUENAME ) {
|
---|
148 | memcpy( szValue, pb, pTag->cbTag );
|
---|
149 | if ( !strcmp( szValue, pszQueueName )) {
|
---|
150 | printf("Found queue %s\n", szValue );
|
---|
151 | hObj = (HOBJECT) ulHandle;
|
---|
152 | fFound = TRUE;
|
---|
153 | }
|
---|
154 | }
|
---|
155 | pb += pTag->cbTag;
|
---|
156 | }
|
---|
157 | }
|
---|
158 | }
|
---|
159 | free( pdata );
|
---|
160 | }
|
---|
161 |
|
---|
162 | //--
|
---|
163 |
|
---|
164 | psz += strlen( psz ) + 1;
|
---|
165 | }
|
---|
166 |
|
---|
167 | free ( pbuf );
|
---|
168 | return ( hObj );
|
---|
169 | }
|
---|
170 |
|
---|
171 |
|
---|
172 | int main( int argc, char *argv[] )
|
---|
173 | {
|
---|
174 | HOBJECT hObj;
|
---|
175 |
|
---|
176 | if ( argc < 2 ) {
|
---|
177 | printf("Missing argument.\nUsage:\tOBJTEST <queue>\n");
|
---|
178 | return 1;
|
---|
179 | }
|
---|
180 |
|
---|
181 | hObj = PrinterObjectHandle( argv[1] );
|
---|
182 | if ( !hObj )
|
---|
183 | printf("Printer object for queue \"%s\" not found.\n", argv[1] );
|
---|
184 | else
|
---|
185 | printf("Printer object for queue \"%s\": %X.\n", argv[1], hObj );
|
---|
186 |
|
---|
187 | return 0;
|
---|
188 | }
|
---|