source: rxprtutl/trunk/objtest.c@ 11

Last change on this file since 11 was 11, checked in by Alex Taylor, 12 years ago

Rewrote PrinterObjectHandle function.

File size: 6.7 KB
Line 
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)
34typedef 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
41typedef 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 * ------------------------------------------------------------------------- */
66HOBJECT 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
172int 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}
Note: See TracBrowser for help on using the repository browser.