Changeset 8 for rxprtutl/trunk/rxprtutl.c
- Timestamp:
- Apr 6, 2013, 8:45:22 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
rxprtutl/trunk/rxprtutl.c
r7 r8 88 88 #define US_PRTINFO_MAXZ 180 // ...of a printer info string 89 89 #define US_PORT_MAXZ 64 // ...of a port name 90 #define US_ SS_MAXZ 256 // ...of a default WPS setup string90 #define US_PRTDEV_MAXZ 9 // ...of a print device name 91 91 92 92 // List of functions to be registered by RPULoadFuncs … … 138 138 HOBJECT PrinterObjectHandle( PSZ pszQueueName ); 139 139 BOOL SaveResultString( PRXSTRING prsResult, PCH pchBytes, ULONG ulBytes ); 140 ULONG UniqueDeviceName( PSZ pszName ); 140 141 BOOL WriteCompoundVariable( PSZ pszStem, PSZ pszTail, PSZ pszValue ); 141 142 BOOL WriteStemElement( PSZ pszStem, ULONG ulIndex, PSZ pszValue ); … … 1013 1014 * * 1014 1015 * Creates a new local printer object. The associated print queue and * 1015 * device are also created if they do not exist. However, the associated*1016 * output port must exist, and the specified printer driver/model must have*1017 * been installed already.*1018 * * 1019 * The WPS object is created with default settings (other than those which*1020 * are specified here). It will be assigned an object-ID automatically.*1021 * * 1022 * This function will not create a remote (LAN) printer object.*1016 * device are created automatically. However, the specified output port * 1017 * must exist, and the specified printer driver/model must have been * 1018 * installed already. * 1019 * * 1020 * The WPS object is created with default settings, and will be assigned an * 1021 * object-ID automatically by the WPS. * 1022 * * 1023 * NOTE: This function will NOT create a remote (LAN) printer object. * 1023 1024 * * 1024 1025 * REXX ARGUMENTS: * 1025 * 1. The name of the print queue, to be created if necessary. (REQUIRED) * 1026 * 2. The "physical name" of the printer device, ditto. (REQUIRED) * 1026 * 1. The printer description, used as the WPS object title. (REQUIRED) * 1027 * 2. The name of the underlying print queue. Must be a legal * 1028 * queue name according to OS/2 (but what is that...?) (REQUIRED) * 1027 1029 * 3. The name of the printer port, which must exist already. (REQUIRED) * 1028 1030 * 4. The default printer driver.model to be associated with * 1029 * the device. If specified, this must be installed in the * 1030 * system already. If not specified, and the named printer * 1031 * device does not already exist, IBMNULL will be assumed. (OPTIONAL) * 1032 * 5. The printer object title (i.e. human-readable name). If * 1033 * not specified, the physical name will be used. (OPTIONAL) * 1031 * the device. If specified, this must be installed in the * 1032 * system already. If not specified, IBMNULL is assumed. (OPTIONAL) * 1034 1033 * * 1035 1034 * REXX RETURN VALUE: * … … 1040 1039 PRDINFO3 devinfo = {0}; 1041 1040 PRQINFO3 qinfo = {0}; 1042 ULONG cbBuf = 0;1043 BOOL fNewD = FALSE;1044 1041 PSZ pszQueueName = NULL, 1045 pszDeviceName = NULL,1046 1042 pszPortName = NULL, 1047 1043 pszModel = NULL, 1048 1044 pszTitle = NULL; 1045 CHAR szDevice[ US_PRTDEV_MAXZ ] = {0}; 1049 1046 SPLERR rc; 1050 1047 … … 1054 1051 1055 1052 // Validate the REXX arguments 1056 if (( argc < 3 ) || ( argc > 5) || ( ! RXVALIDSTRING( argv[0] )) ||1053 if (( argc < 3 ) || ( argc > 4 ) || ( ! RXVALIDSTRING( argv[0] )) || 1057 1054 ( ! RXVALIDSTRING( argv[1] )) || ( ! RXVALIDSTRING( argv[2] ))) 1058 1055 return ( 40 ); 1059 1056 if (( argc > 3 ) && ( ! RXVALIDSTRING( argv[3] ))) 1060 1057 return ( 40 ); 1061 if (( argc > 4 ) && ( ! RXVALIDSTRING( argv[4] ))) 1062 return ( 40 ); 1063 1064 pszQueueName = argv[0].strptr; 1065 pszDeviceName = argv[1].strptr; 1058 1059 pszTitle = argv[0].strptr; 1060 pszQueueName = argv[1].strptr; 1066 1061 pszPortName = argv[2].strptr; 1067 1062 if ( argc > 3 ) pszModel = argv[3].strptr; 1068 pszTitle = ( argc > 4 ) ? argv[4].strptr : pszDeviceName; 1069 1070 // Find out if device exists already 1071 rc = SplQueryDevice( NULL, pszDeviceName, 0, NULL, 0, &cbBuf ); 1072 if ( rc == NERR_DestNotFound ) { 1073 1074 // Nope, create it now 1075 devinfo.pszPrinterName = pszDeviceName; 1076 devinfo.pszUserName = NULL; 1077 devinfo.pszLogAddr = pszPortName; 1078 devinfo.pszComment = pszTitle; 1079 devinfo.pszDrivers = pszModel ? pszModel : "IBMNULL"; 1080 devinfo.usTimeOut = 45; 1081 rc = SplCreateDevice( NULL, 3, &devinfo, sizeof( devinfo )); 1082 if ( rc != NO_ERROR ) { 1083 WriteErrorCode( rc, "SplCreateDevice"); 1084 MAKERXSTRING( *prsResult, "0", 1 ); 1085 return ( 0 ); 1086 } 1087 fNewD = TRUE; 1088 } 1089 else if ( rc != NO_ERROR ) { 1090 WriteErrorCode( rc, "SplQueryDevice"); 1063 1064 // Generate a suitable (unique) device name, based on the queue name 1065 strncpy( szDevice, pszQueueName, US_PRTDEV_MAXZ-1 ); 1066 if (( rc = UniqueDeviceName( szDevice )) != NO_ERROR ) { 1067 if ( rc == 1 ) // shouldn't really happen 1068 WriteErrorCode( rc, "UniqueDeviceName"); 1069 else 1070 WriteErrorCode( rc, "SplEnumDevice"); 1091 1071 MAKERXSTRING( *prsResult, "0", 1 ); 1092 1072 return ( 0 ); 1093 1073 } 1094 1074 1095 // Find out if the queue name already exists 1096 rc = SplQueryQueue( NULL, pszQueueName, 3, NULL, 0, &cbBuf ); 1097 if ( rc == NERR_QNotFound ) { 1098 1099 // Nope, create it now 1100 qinfo.pszName = pszQueueName; 1101 qinfo.uPriority = PRQ_DEF_PRIORITY; 1102 qinfo.fsType = PRQ3_TYPE_RAW; 1103 qinfo.pszPrProc = "PMPRINT"; 1104 qinfo.pszComment = pszTitle; 1105 qinfo.pszPrinters = pszDeviceName; 1106 qinfo.pszDriverName = pszModel ? pszModel : "IBMNULL"; 1107 rc = SplCreateQueue( NULL, 3, &qinfo, sizeof( qinfo )); 1108 if ( rc != NO_ERROR ) { 1109 WriteErrorCode( rc, "SplCreateQueue"); 1110 MAKERXSTRING( *prsResult, "0", 1 ); 1111 if ( fNewD ) SplDeleteDevice( NULL, pszDeviceName ); 1112 return ( 0 ); 1113 } 1114 } 1115 else if ( rc != NO_ERROR ) { 1116 WriteErrorCode( rc, "SplQueryQueue"); 1117 MAKERXSTRING( *prsResult, "0", 1 ); 1118 if ( fNewD ) SplDeleteDevice( NULL, pszDeviceName ); 1075 // Create the device 1076 devinfo.pszPrinterName = szDevice; 1077 devinfo.pszUserName = NULL; 1078 devinfo.pszLogAddr = pszPortName; 1079 devinfo.pszComment = pszTitle; 1080 devinfo.pszDrivers = pszModel ? pszModel : "IBMNULL"; 1081 devinfo.usTimeOut = 45; 1082 rc = SplCreateDevice( NULL, 3, &devinfo, sizeof( devinfo )); 1083 if ( rc != NO_ERROR ) { 1084 WriteErrorCode( rc, "SplCreateDevice"); 1085 MAKERXSTRING( *prsResult, "0", 1 ); 1086 return ( 0 ); 1087 } 1088 1089 // Create the queue (automatically creates printer object) 1090 qinfo.pszName = pszQueueName; 1091 qinfo.uPriority = PRQ_DEF_PRIORITY; 1092 qinfo.fsType = PRQ3_TYPE_RAW; 1093 qinfo.pszPrProc = "PMPRINT"; 1094 qinfo.pszComment = pszTitle; 1095 qinfo.pszPrinters = szDevice; 1096 qinfo.pszDriverName = pszModel ? pszModel : "IBMNULL"; 1097 rc = SplCreateQueue( NULL, 3, &qinfo, sizeof( qinfo )); 1098 if ( rc != NO_ERROR ) { 1099 WriteErrorCode( rc, "SplCreateQueue"); 1100 MAKERXSTRING( *prsResult, "0", 1 ); 1101 SplDeleteDevice( NULL, szDevice ); 1119 1102 return ( 0 ); 1120 1103 } … … 1507 1490 1508 1491 1492 /* ------------------------------------------------------------------------- * 1493 * UniqueDeviceName * 1494 * * 1495 * Check (and, if necessary, modify) the specified print device name to make * 1496 * sure it is unique. * 1497 * * 1498 * ARGUMENTS: * 1499 * PSZ pszName : Pointer to device name buffer (9-byte CHAR buffer) * 1500 * * 1501 * RETURNS: ULONG * 1502 * 0 on success, 1 if no unique name could be generated, or the return * 1503 * code from SplEnumDevice() if an error occurred. * 1504 * ------------------------------------------------------------------------- */ 1505 ULONG UniqueDeviceName( PSZ pszName ) 1506 { 1507 PBYTE pBuf; 1508 PPRDINFO3 pprd3; 1509 CHAR szNumber[ US_PRTDEV_MAXZ ] = {0}; 1510 ULONG i, n, pos, 1511 ulNumber = 0, 1512 ulAvail = 0, 1513 cbBuf = 0; 1514 BOOL fUnique = FALSE; 1515 SPLERR rc; 1516 1517 1518 rc = SplEnumDevice( NULL, 3, NULL, 0, &ulNumber, &ulAvail, &cbBuf, NULL ); 1519 if ( rc == ERROR_MORE_DATA || rc == NERR_BufTooSmall ) { 1520 pBuf = malloc( cbBuf ); 1521 if ( pBuf ) { 1522 rc = SplEnumDevice( NULL, 3, pBuf, cbBuf, &ulNumber, &ulAvail, &cbBuf, NULL ); 1523 if ( rc == NO_ERROR ) { 1524 n = 1; 1525 while ( !fUnique && ( n < 999 )) { // max 999 as a sanity check 1526 for ( i = 0; i < ulNumber; i++ ) { 1527 pprd3 = (PPRDINFO3) pBuf + i; 1528 if ( stricmp( pszName, pprd3->pszPrinterName ) == 0 ) break; 1529 } 1530 if ( i >= ulNumber ) fUnique = TRUE; 1531 else { 1532 sprintf( szNumber, "%u", n++ ); 1533 pos = strlen( pszName ) - strlen( szNumber ); 1534 pszName[ pos ] = '\0'; 1535 strncat( pszName, szNumber, US_PRTDEV_MAXZ-1 ); 1536 } 1537 } 1538 } 1539 free( pBuf ); 1540 } 1541 } 1542 if ( rc == NO_ERROR && !fUnique ) return 1; 1543 else return rc; 1544 } 1545 1546 1509 1547 /* ************************************************************************* * 1510 1548 * INTERNAL REXX DLL UTILITY FUNCTIONS *
Note:
See TracChangeset
for help on using the changeset viewer.