| [11] | 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 | }
 | 
|---|