#define INCL_DEV #define INCL_DOSERRORS #define INCL_DOSMISC #define INCL_DOSPROFILE #define INCL_SPL #define INCL_SPLDOSPRINT #define INCL_SPLERRORS #define INCL_PM #define INCL_WIN #ifndef OS2_INCLUDED #include #endif #include #include #include #include // CONSTANTS #define APPNAME_PM_PRINT_OBJECT "PM_PrintObject" #define APPNAME_PM_ABS_OBJECTS "PM_Abstract:Objects" #define APPNAME_PM_WPS_LOCATION "PM_Workplace:Location" #define ID_OBJINFO_QUEUENAME 3 #define ID_OBJINFO_RPQUEUENAME 13 // DATA TYPES /* Structures needed used to parse PM_Abstract:Object data */ #pragma pack(1) typedef struct _Object_Info { USHORT cbName; // Size of szName, including terminator USHORT cbData; // Number of additional data bytes following szName CHAR szName[1]; // Name of object type } OBJINFO, *POBJINFO; typedef struct _Object_Tag_Info { USHORT usTagFormat; // Tag data format USHORT usTag; // Tag ID USHORT cbTag; // Size of tag data } OITAG, *POITAG; #pragma pack() /* ------------------------------------------------------------------------- * * PrinterObjectHandle * * * * Given a print queue name, obtain the handle to the WPS printer object * * associated with that queue. This is done by querying OS2.INI for the * * queues defined in PM_PrintObject and reading the associated handle IDs. * * * * ARGUMENTS: * * PSZ pszQueueName: The printer queue name. This is NOT the same as the * * printer device name, although in many cases they may * * have the same value. * * * * RETURNS: HOBJECT * * WPS object handle of the printer object; NULLHANDLE if no object was * * found or an error occurred. * * ------------------------------------------------------------------------- */ HOBJECT PrinterObjectHandle( PSZ pszQueueName ) { PVOID pbuf = NULL, pdata = NULL; PBYTE pb, pbEnd, pbGrpEnd; POBJINFO pInfo = NULL; POITAG pTag = NULL; PSZ psz, pszName; CHAR szValue[ 256 ], szObject[ 5 ]; ULONG cbTotal = 0, cbActual = 0, ulHandle; HOBJECT hObj = 0; BOOL fFound, fRC; fRC = PrfQueryProfileSize( HINI_USERPROFILE, APPNAME_PM_PRINT_OBJECT, NULL, &cbTotal ); if ( !fRC || !cbTotal ) { return NULLHANDLE; } pbuf = malloc( cbTotal ); if ( !pbuf ) { return NULLHANDLE; } cbActual = PrfQueryProfileString( HINI_USERPROFILE, APPNAME_PM_PRINT_OBJECT, NULL, NULL, pbuf, cbTotal ); if ( !cbActual ) { return NULLHANDLE; } fFound = FALSE; psz = (PSZ) pbuf; while ( *psz && !fFound ) { // -- if ( sscanf( psz, "%u", &ulHandle ) && LOUSHORT( ulHandle )) { printf("Checking printer object %X\n", ulHandle ); sprintf( szObject, "%X", LOUSHORT( ulHandle )); fRC = PrfQueryProfileSize( HINI_USERPROFILE, APPNAME_PM_ABS_OBJECTS, szObject, &cbTotal ); if ( !fRC || ( cbTotal < 25 ) || ((pdata = malloc( cbTotal )) == NULL )) { psz += strlen( psz ) + 1; continue; } if ( PrfQueryProfileData( HINI_USERPROFILE, APPNAME_PM_ABS_OBJECTS, szObject, (PVOID) pdata, &cbTotal )) { BOOL fRemote; pbEnd = (PBYTE) pdata + cbTotal; pszName = (PSZ) pdata + sizeof( ULONG ); fRemote = strcmp( pszName, "WPRPrinter") ? FALSE : TRUE; pb = (PBYTE) pszName + strlen( pszName ) + 17; while (( pb < pbEnd ) && !fFound ) { pInfo = (POBJINFO) pb; pb += sizeof( OBJINFO ) + strlen( pInfo->szName ); pbGrpEnd = pb + pInfo->cbData; if ( pbGrpEnd > pbEnd ) pbGrpEnd = pbEnd; while (( pb < pbGrpEnd ) && !fFound ) { pTag = (POITAG) pb; pb += sizeof( OITAG ); //printf(" - checking tag: %x\n", pTag->usTag ); /* For network printers, tag ID 3 indicates the name of * the queue on the remote server. We want the local * queue name, which has tag ID 13. */ if ( fRemote && ( pTag->usTag == ID_OBJINFO_RPQUEUENAME )) { memcpy( szValue, pb, pTag->cbTag ); if ( !strcmp( szValue, pszQueueName )) { printf("Found queue %s\n", szValue ); hObj = (HOBJECT) ulHandle; fFound = TRUE; } } // For local printers, just look for tag ID 3 else if ( pTag->usTag == ID_OBJINFO_QUEUENAME ) { memcpy( szValue, pb, pTag->cbTag ); if ( !strcmp( szValue, pszQueueName )) { printf("Found queue %s\n", szValue ); hObj = (HOBJECT) ulHandle; fFound = TRUE; } } pb += pTag->cbTag; } } } free( pdata ); } //-- psz += strlen( psz ) + 1; } free ( pbuf ); return ( hObj ); } int main( int argc, char *argv[] ) { HOBJECT hObj; if ( argc < 2 ) { printf("Missing argument.\nUsage:\tOBJTEST \n"); return 1; } hObj = PrinterObjectHandle( argv[1] ); if ( !hObj ) printf("Printer object for queue \"%s\" not found.\n", argv[1] ); else printf("Printer object for queue \"%s\": %X.\n", argv[1], hObj ); return 0; }