| 1 | /* SMBPORT
|
|---|
| 2 | *
|
|---|
| 3 | * Simple program to create a new SMB printer port using the specified
|
|---|
| 4 | * host/queue/password.
|
|---|
| 5 | *
|
|---|
| 6 | * Syntax: smbport <port-name> <workgroup> <host> <printer> [<user-id> [<password>]]
|
|---|
| 7 | */
|
|---|
| 8 |
|
|---|
| 9 | #define INCL_DOSERRORS
|
|---|
| 10 | #define INCL_DOSMODULEMGR
|
|---|
| 11 | #define INCL_DOSPROCESS
|
|---|
| 12 | #define INCL_GPI
|
|---|
| 13 | #define INCL_SPL
|
|---|
| 14 | #define INCL_SPLERRORS
|
|---|
| 15 | #define INCL_WIN
|
|---|
| 16 | #include <os2.h>
|
|---|
| 17 | #include <stdio.h>
|
|---|
| 18 | #include <stdlib.h>
|
|---|
| 19 | #include <string.h>
|
|---|
| 20 |
|
|---|
| 21 | #define STR_LEN_PORTNAME 64
|
|---|
| 22 | #define STR_LEN_PORTDESC 256
|
|---|
| 23 | #define STR_LEN_DESC 81
|
|---|
| 24 |
|
|---|
| 25 | #define APPNAME_LEAD_STR "PM_"
|
|---|
| 26 | #define APPNAME_PM_PORT_DRIVER "PM_PORT_DRIVER"
|
|---|
| 27 | #define APPNAME_PM_SPOOLER_PORT "PM_SPOOLER_PORT"
|
|---|
| 28 |
|
|---|
| 29 | #define KEY_DESCRIPTION "DESCRIPTION"
|
|---|
| 30 | #define KEY_INITIALIZATION "INITIALIZATION"
|
|---|
| 31 | #define KEY_TERMINATION "TERMINATION"
|
|---|
| 32 | #define KEY_PORTDRIVER "PORTDRIVER"
|
|---|
| 33 | #define KEY_TIMEOUT "TIMEOUT"
|
|---|
| 34 |
|
|---|
| 35 | /* Driver-specific port setting structure for SplPdSet & SplPdQuery.
|
|---|
| 36 | */
|
|---|
| 37 | typedef struct _PORTSETTINGS {
|
|---|
| 38 | CHAR szPortData[ STR_LEN_PORTDESC ];
|
|---|
| 39 | } PORTSETTINGS, *PPORTSETTINGS;
|
|---|
| 40 |
|
|---|
| 41 |
|
|---|
| 42 | /* Various items that should be defined in the toolkit header pmsplb.h,
|
|---|
| 43 | * if it actually existed...
|
|---|
| 44 | */
|
|---|
| 45 | #define TYPE_LONG_WAIT 2
|
|---|
| 46 | #define BIDI_SET_PORTDRV 0x19
|
|---|
| 47 |
|
|---|
| 48 | #pragma import ( PrtSet,, "PMSPL", 604 )
|
|---|
| 49 | extern ULONG APIENTRY PrtSet( PSZ pszComputerName, PSZ pszDeviceName, ULONG ulType, ULONG ulCommand, PVOID pInData, ULONG cbInData );
|
|---|
| 50 |
|
|---|
| 51 |
|
|---|
| 52 | /* Copied from smb.c
|
|---|
| 53 | */
|
|---|
| 54 |
|
|---|
| 55 | static char tohex (unsigned char b)
|
|---|
| 56 | {
|
|---|
| 57 | b &= 0xF;
|
|---|
| 58 |
|
|---|
| 59 | if (b <= 9)
|
|---|
| 60 | {
|
|---|
| 61 | return b + '0';
|
|---|
| 62 | }
|
|---|
| 63 |
|
|---|
| 64 | return 'A' + (b - 0xA);
|
|---|
| 65 | }
|
|---|
| 66 |
|
|---|
| 67 | static void encryptPassword (const char *pszPlain, char *pszCrypt)
|
|---|
| 68 | {
|
|---|
| 69 | /* A simple "encryption" encode each character as hex value. */
|
|---|
| 70 | const char *s = pszPlain;
|
|---|
| 71 | char *d = pszCrypt;
|
|---|
| 72 |
|
|---|
| 73 | while (*s)
|
|---|
| 74 | {
|
|---|
| 75 | *d++ = tohex ((*s) >> 4);
|
|---|
| 76 | *d++ = tohex (*s);
|
|---|
| 77 | s++;
|
|---|
| 78 | }
|
|---|
| 79 |
|
|---|
| 80 | *d++ = 0;
|
|---|
| 81 | }
|
|---|
| 82 |
|
|---|
| 83 |
|
|---|
| 84 | int main( int argc, char *argv[] )
|
|---|
| 85 | {
|
|---|
| 86 | PORTSETTINGS settings;
|
|---|
| 87 |
|
|---|
| 88 | HAB hab;
|
|---|
| 89 | ULONG ulRC;
|
|---|
| 90 | PSZ pszPortName = NULL,
|
|---|
| 91 | pszHostName = NULL,
|
|---|
| 92 | pszPrinterName = NULL,
|
|---|
| 93 | pszWorkgroup = NULL,
|
|---|
| 94 | pszUserID = NULL,
|
|---|
| 95 | pszPassword = NULL,
|
|---|
| 96 | pszCopies = NULL;
|
|---|
| 97 | CHAR szPathName[ CCHMAXPATH + 1 ];
|
|---|
| 98 | CHAR szIniApp[ STR_LEN_PORTNAME ];
|
|---|
| 99 | CHAR szIniVal[ STR_LEN_PORTDESC ];
|
|---|
| 100 | CHAR pwBuffer[ 256 ];
|
|---|
| 101 | HMODULE hPdr = NULLHANDLE;
|
|---|
| 102 | PFN pfn_SmbInstallPort,
|
|---|
| 103 | pfn_SmbSet;
|
|---|
| 104 |
|
|---|
| 105 |
|
|---|
| 106 | if ( argc < 5 ) {
|
|---|
| 107 | printf("SMBPORT - Create a new Samba printer port for the specified SMB network printer\n");
|
|---|
| 108 | printf("Syntax:\n smbport <port> <workgroup> <host> <printer> [<userid>] [<password>] [<copies>]\n");
|
|---|
| 109 | printf(" <port> Name of the new port (must be \"SMB<x>\", where <x> = 1-64)\n");
|
|---|
| 110 | printf(" <workgroup> Name of the SMB workgroup to which the host and printer belong\n");
|
|---|
| 111 | printf(" <host> SMB host name of the server where the printer is defined\n");
|
|---|
| 112 | printf(" <printer> SMB name of the destination printer on <host>\n");
|
|---|
| 113 | printf(" <userid> SMB user name authorized to access the printer\n");
|
|---|
| 114 | printf(" <password> The password for <user-id>\n");
|
|---|
| 115 | printf(" <copies> Number of copies of each job to print\n");
|
|---|
| 116 | printf(" To leave a parameter empty, specify \"\"\n");
|
|---|
| 117 | printf("\nExamples:\n smbport SMB1 \"\" printsrv hplj4a guest guest\n");
|
|---|
| 118 | printf(" smbport SMB2 yggdrasill valhalla printer6 odin all-seeing 1\n");
|
|---|
| 119 | return 1;
|
|---|
| 120 | }
|
|---|
| 121 | pszPortName = strupr( argv[ 1 ] );
|
|---|
| 122 | pszWorkgroup = argv[ 2 ];
|
|---|
| 123 | pszHostName = argv[ 3 ];
|
|---|
| 124 | pszPrinterName = argv[ 4 ];
|
|---|
| 125 | if ( argc > 4 ) pszUserID = argv[ 5 ];
|
|---|
| 126 | if ( argc > 5 ) pszPassword = argv[ 6 ];
|
|---|
| 127 | if ( argc > 6 ) pszCopies = argv[ 7 ];
|
|---|
| 128 |
|
|---|
| 129 | /* Get the path to the installed SMB.PDR */
|
|---|
| 130 | hab = WinInitialize( 0 );
|
|---|
| 131 | ulRC = PrfQueryProfileString( HINI_SYSTEMPROFILE, APPNAME_PM_PORT_DRIVER,
|
|---|
| 132 | "SMB", NULL, (PVOID) szPathName, CCHMAXPATH );
|
|---|
| 133 | if ( !ulRC ) {
|
|---|
| 134 | ulRC = ulRC = WinGetLastError( hab );
|
|---|
| 135 | printf("SMB port driver is not installed.\n");
|
|---|
| 136 | WinTerminate( hab );
|
|---|
| 137 | return ulRC;
|
|---|
| 138 | }
|
|---|
| 139 |
|
|---|
| 140 | /* Now load the port driver DLL and register the install and setup functions */
|
|---|
| 141 | ulRC = DosLoadModule( NULL, 0, szPathName, &hPdr );
|
|---|
| 142 | if ( ulRC != NO_ERROR ) {
|
|---|
| 143 | printf("Failed to load SMB.PDR, RC=%u.\n", ulRC );
|
|---|
| 144 | WinTerminate( hab );
|
|---|
| 145 | return ulRC;
|
|---|
| 146 | }
|
|---|
| 147 | ulRC = DosQueryProcAddr( hPdr, 0, "SPLPDINSTALLPORT", &pfn_SmbInstallPort );
|
|---|
| 148 | if ( ulRC != NO_ERROR ) {
|
|---|
| 149 | printf("Failed to resolve proc address, RC=%u.\n", ulRC );
|
|---|
| 150 | goto finish;
|
|---|
| 151 | }
|
|---|
| 152 | ulRC = DosQueryProcAddr( hPdr, 0, "SPLPDSET", &pfn_SmbSet );
|
|---|
| 153 | if ( ulRC != NO_ERROR ) {
|
|---|
| 154 | printf("Failed to resolve proc address, RC=%u.\n", ulRC );
|
|---|
| 155 | goto finish;
|
|---|
| 156 | }
|
|---|
| 157 |
|
|---|
| 158 | /* Create the new port (it will be given default settings by the PDR) */
|
|---|
| 159 | ulRC = pfn_SmbInstallPort( hab, pszPortName );
|
|---|
| 160 | if ( ulRC != NO_ERROR ) {
|
|---|
| 161 | printf("Failed to create port, RC=0x%X.\n", ulRC );
|
|---|
| 162 | goto finish;
|
|---|
| 163 | }
|
|---|
| 164 | printf("Port %s was created successfully.\n", pszPortName );
|
|---|
| 165 |
|
|---|
| 166 | /* Now update the port driver settings */
|
|---|
| 167 | strncpy( settings.szPortData, pszHostName, STR_LEN_PORTDESC-1 );
|
|---|
| 168 | strncat( settings.szPortData, "#", STR_LEN_PORTDESC-1 );
|
|---|
| 169 | strncat( settings.szPortData, pszPrinterName, STR_LEN_PORTDESC-1 );
|
|---|
| 170 | strncat( settings.szPortData, "#", STR_LEN_PORTDESC-1 );
|
|---|
| 171 | if ( pszWorkgroup && (strlen( pszWorkgroup )))
|
|---|
| 172 | strncat( settings.szPortData, pszWorkgroup, STR_LEN_PORTDESC-1 );
|
|---|
| 173 | strncat( settings.szPortData, "#", STR_LEN_PORTDESC-1 );
|
|---|
| 174 | if ( pszUserID && ( strlen( pszUserID )))
|
|---|
| 175 | strncat( settings.szPortData, pszUserID, STR_LEN_PORTDESC-1 );
|
|---|
| 176 | strncat( settings.szPortData, "#", STR_LEN_PORTDESC-1 );
|
|---|
| 177 | if ( pszCopies && ( strlen( pszCopies )))
|
|---|
| 178 | strncat( settings.szPortData, pszCopies, STR_LEN_PORTDESC-1 );
|
|---|
| 179 | strncat( settings.szPortData, "#", STR_LEN_PORTDESC-1 );
|
|---|
| 180 | if ( pszPassword && ( strlen( pszPassword ))) {
|
|---|
| 181 | encryptPassword( pszPassword, pwBuffer );
|
|---|
| 182 | strncat( settings.szPortData, pwBuffer, STR_LEN_PORTDESC-1 );
|
|---|
| 183 | }
|
|---|
| 184 | printf("Setting port data: %s\n", settings.szPortData );
|
|---|
| 185 | ulRC = pfn_SmbSet( pszPortName, TYPE_LONG_WAIT, BIDI_SET_PORTDRV,
|
|---|
| 186 | &settings, sizeof( settings ));
|
|---|
| 187 | if ( ulRC ) {
|
|---|
| 188 | printf("Failed to update port settings, RC=0x%X.\n", ulRC );
|
|---|
| 189 | goto finish;
|
|---|
| 190 | }
|
|---|
| 191 |
|
|---|
| 192 | /* Make sure the settings actually were updated (older versions of SMB.PDR
|
|---|
| 193 | * don't do anything when SplPdSet is called, but return success anyway).
|
|---|
| 194 | * What we do here is read the port settings directly from the INI file
|
|---|
| 195 | * and compare it with the data we sent.
|
|---|
| 196 | */
|
|---|
| 197 | strcpy( szIniApp, APPNAME_LEAD_STR );
|
|---|
| 198 | strncat( szIniApp, pszPortName, STR_LEN_PORTNAME-1 );
|
|---|
| 199 | ulRC = PrfQueryProfileString( HINI_SYSTEMPROFILE, szIniApp,
|
|---|
| 200 | KEY_INITIALIZATION, NULL,
|
|---|
| 201 | (PVOID) szIniVal, STR_LEN_PORTDESC );
|
|---|
| 202 | if ( !ulRC ) {
|
|---|
| 203 | ulRC = 1;
|
|---|
| 204 | printf("Failed to get SMB port settings for %s: 0x%X\n", szIniApp, WinGetLastError( hab ));
|
|---|
| 205 | goto finish;
|
|---|
| 206 | }
|
|---|
| 207 | if ( strncmp( szIniVal, settings.szPortData, strlen( settings.szPortData ))) {
|
|---|
| 208 | printf("Unable to set SMB port settings.\n");
|
|---|
| 209 | ulRC = 1;
|
|---|
| 210 | }
|
|---|
| 211 | else {
|
|---|
| 212 | printf("Port settings were updated successfully.\n");
|
|---|
| 213 | ulRC = 0;
|
|---|
| 214 | }
|
|---|
| 215 |
|
|---|
| 216 | finish:
|
|---|
| 217 | if ( hPdr ) DosFreeModule( hPdr );
|
|---|
| 218 | WinTerminate( hab );
|
|---|
| 219 |
|
|---|
| 220 | return ulRC;
|
|---|
| 221 | }
|
|---|
| 222 |
|
|---|