mirror of
https://github.com/samba-team/samba.git
synced 2025-02-03 13:47:25 +03:00
Two OS/2 printer fixes from Jim McDonough @ IBM.
First one adds a new info level into the lanman printing and an ioctl to the trans2 code. Andrew - this uses ASCII only. It looks ok to me but please check ! Second one adds a parameter "os2 driver map" that allows OS/2 driver names to be mapped. Jeremy. (This used to be commit da79b519e0b6b4317d7fb5260d74e0e74a7e0b46)
This commit is contained in:
parent
da8805b377
commit
a447217509
@ -1566,6 +1566,7 @@ char *lp_printcapname(void);
|
||||
char *lp_enumports_cmd(void);
|
||||
char *lp_addprinter_cmd(void);
|
||||
char *lp_deleteprinter_cmd(void);
|
||||
char *lp_os2_driver_map(void);
|
||||
char *lp_lockdir(void);
|
||||
char *lp_utmpdir(void);
|
||||
char *lp_wtmpdir(void);
|
||||
|
@ -107,6 +107,7 @@ typedef struct
|
||||
char *szEnumPortsCommand;
|
||||
char *szAddPrinterCommand;
|
||||
char *szDeletePrinterCommand;
|
||||
char *szOs2DriverMap;
|
||||
char *szLockDir;
|
||||
char *szRootdir;
|
||||
char *szDefaultService;
|
||||
@ -846,6 +847,7 @@ static struct parm_struct parm_table[] = {
|
||||
{"addprinter command", P_STRING, P_GLOBAL, &Globals.szAddPrinterCommand, NULL, NULL, 0},
|
||||
{"deleteprinter command", P_STRING, P_GLOBAL, &Globals.szDeletePrinterCommand, NULL, NULL, 0},
|
||||
{"show add printer wizard", P_BOOL, P_GLOBAL, &Globals.bMsAddPrinterWizard, NULL, NULL, 0},
|
||||
{"os2 driver map", P_STRING, P_GLOBAL, &Globals.szOs2DriverMap, NULL, NULL, 0},
|
||||
|
||||
{"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT|FLAG_DOS_STRING},
|
||||
{"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_DOS_STRING},
|
||||
@ -1435,6 +1437,7 @@ FN_GLOBAL_STRING(lp_printcapname, &Globals.szPrintcapname)
|
||||
FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
|
||||
FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
|
||||
FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
|
||||
FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
|
||||
FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
|
||||
#ifdef WITH_UTMP
|
||||
FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
|
||||
|
@ -2135,6 +2135,86 @@ static int unpack_specifics(NT_PRINTER_PARAM **list, char *buf, int buflen)
|
||||
return len;
|
||||
}
|
||||
|
||||
static void map_to_os2_driver(fstring drivername)
|
||||
{
|
||||
static BOOL initialised=False;
|
||||
static fstring last_from,last_to;
|
||||
char *mapfile = lp_os2_driver_map();
|
||||
char **lines = NULL;
|
||||
int numlines = 0;
|
||||
int i;
|
||||
|
||||
if (!strlen(drivername))
|
||||
return;
|
||||
|
||||
if (!*mapfile)
|
||||
return;
|
||||
|
||||
if (!initialised) {
|
||||
*last_from = *last_to = 0;
|
||||
initialised = True;
|
||||
}
|
||||
|
||||
if (strequal(drivername,last_from)) {
|
||||
DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",drivername,last_to));
|
||||
fstrcpy(drivername,last_to);
|
||||
return;
|
||||
}
|
||||
|
||||
lines = file_lines_load(mapfile, &numlines, True);
|
||||
if (numlines == 0) {
|
||||
DEBUG(0,("No entries in OS/2 driver map %s\n",mapfile));
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG(4,("Scanning OS/2 driver map %s\n",mapfile));
|
||||
|
||||
for( i = 0; i < numlines; i++) {
|
||||
char *nt_name = lines[i];
|
||||
char *os2_name = strchr(nt_name,'=');
|
||||
|
||||
if (!os2_name)
|
||||
continue;
|
||||
|
||||
*os2_name++ = 0;
|
||||
|
||||
while (isspace(*nt_name))
|
||||
nt_name++;
|
||||
|
||||
if (!*nt_name || strchr("#;",*nt_name))
|
||||
continue;
|
||||
|
||||
{
|
||||
int l = strlen(nt_name);
|
||||
while (l && isspace(nt_name[l-1])) {
|
||||
nt_name[l-1] = 0;
|
||||
l--;
|
||||
}
|
||||
}
|
||||
|
||||
while (isspace(*os2_name))
|
||||
os2_name++;
|
||||
|
||||
{
|
||||
int l = strlen(os2_name);
|
||||
while (l && isspace(os2_name[l-1])) {
|
||||
os2_name[l-1] = 0;
|
||||
l--;
|
||||
}
|
||||
}
|
||||
|
||||
if (strequal(nt_name,drivername)) {
|
||||
DEBUG(3,("Mapped windows driver %s to os2 driver%s\n",drivername,os2_name));
|
||||
fstrcpy(last_from,drivername);
|
||||
fstrcpy(last_to,os2_name);
|
||||
fstrcpy(drivername,os2_name);
|
||||
file_lines_free(lines);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
file_lines_free(lines);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
get a default printer info 2 struct
|
||||
@ -2273,6 +2353,11 @@ static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharen
|
||||
|
||||
nt_printing_getsec(get_talloc_ctx(), sharename, &info.secdesc_buf);
|
||||
|
||||
/* Fix for OS/2 drivers. */
|
||||
|
||||
if (get_remote_arch() == RA_OS2)
|
||||
map_to_os2_driver(info.drivername);
|
||||
|
||||
safe_free(dbuf.dptr);
|
||||
*info_ptr=memdup(&info, sizeof(info));
|
||||
|
||||
|
@ -474,7 +474,7 @@ static void fill_printjob_info(connection_struct *conn, int snum, int uLevel,
|
||||
PACKI(desc,"D",queue->size); /* ulSize */
|
||||
PACKS(desc,"z",queue->file); /* pszComment */
|
||||
}
|
||||
if (uLevel == 2 || uLevel == 3) {
|
||||
if (uLevel == 2 || uLevel == 3 || uLevel == 4) {
|
||||
PACKI(desc,"W",queue->priority); /* uPriority */
|
||||
PACKS(desc,"z",queue->user); /* pszUserName */
|
||||
PACKI(desc,"W",n+1); /* uPosition */
|
||||
@ -494,6 +494,17 @@ static void fill_printjob_info(connection_struct *conn, int snum, int uLevel,
|
||||
PACKS(desc,"z","NULL"); /* pszDriverName */
|
||||
PackDriverData(desc); /* pDriverData */
|
||||
PACKS(desc,"z",""); /* pszPrinterName */
|
||||
} else if (uLevel == 4) { /* OS2 */
|
||||
PACKS(desc,"z",""); /* pszSpoolFileName */
|
||||
PACKS(desc,"z",""); /* pszPortName */
|
||||
PACKS(desc,"z",""); /* pszStatus */
|
||||
PACKI(desc,"D",0); /* ulPagesSpooled */
|
||||
PACKI(desc,"D",0); /* ulPagesSent */
|
||||
PACKI(desc,"D",0); /* ulPagesPrinted */
|
||||
PACKI(desc,"D",0); /* ulTimePrinted */
|
||||
PACKI(desc,"D",0); /* ulExtendJobStatus */
|
||||
PACKI(desc,"D",0); /* ulStartPage */
|
||||
PACKI(desc,"D",0); /* ulEndPage */
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -859,7 +870,8 @@ static BOOL api_DosPrintQGetInfo(connection_struct *conn,
|
||||
struct pack_desc desc;
|
||||
print_queue_struct *queue=NULL;
|
||||
print_status_struct status;
|
||||
|
||||
char* tmpdata=NULL;
|
||||
|
||||
memset((char *)&status,'\0',sizeof(status));
|
||||
memset((char *)&desc,'\0',sizeof(desc));
|
||||
|
||||
@ -907,9 +919,19 @@ static BOOL api_DosPrintQGetInfo(connection_struct *conn,
|
||||
count = print_queue_status(snum, &queue,&status);
|
||||
}
|
||||
|
||||
if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
|
||||
desc.base = *rdata;
|
||||
desc.buflen = mdrcnt;
|
||||
if (mdrcnt > 0) {
|
||||
*rdata = REALLOC(*rdata,mdrcnt);
|
||||
desc.base = *rdata;
|
||||
desc.buflen = mdrcnt;
|
||||
} else {
|
||||
/*
|
||||
* Don't return data but need to get correct length
|
||||
* init_package will return wrong size if buflen=0
|
||||
*/
|
||||
desc.buflen = getlen(desc.format);
|
||||
desc.base = tmpdata = (char *) malloc (desc.buflen);
|
||||
}
|
||||
|
||||
if (init_package(&desc,1,count)) {
|
||||
desc.subcount = count;
|
||||
fill_printq_info(conn,snum,uLevel,&desc,count,queue,&status);
|
||||
@ -948,7 +970,8 @@ static BOOL api_DosPrintQGetInfo(connection_struct *conn,
|
||||
DEBUG(4,("printqgetinfo: errorcode %d\n",desc.errcode));
|
||||
|
||||
if (queue) free(queue);
|
||||
|
||||
if (tmpdata) free (tmpdata);
|
||||
|
||||
return(True);
|
||||
}
|
||||
|
||||
@ -2000,6 +2023,7 @@ static int check_printjob_info(struct pack_desc* desc,
|
||||
case 1: desc->format = "WB21BB16B10zWWzDDz"; break;
|
||||
case 2: desc->format = "WWzWWDDzz"; break;
|
||||
case 3: desc->format = "WWzWWDDzzzzzzzzzzlz"; break;
|
||||
case 4: desc->format = "WWzWWDDzzzzzDDDDDDD"; break;
|
||||
default: return False;
|
||||
}
|
||||
if (strcmp(desc->format,id) != 0) return False;
|
||||
@ -2755,6 +2779,7 @@ static BOOL api_WPrintJobGetInfo(connection_struct *conn,uint16 vuid, char *para
|
||||
struct pack_desc desc;
|
||||
print_queue_struct *queue=NULL;
|
||||
print_status_struct status;
|
||||
char *tmpdata=NULL;
|
||||
|
||||
uLevel = SVAL(p,2);
|
||||
|
||||
@ -2776,9 +2801,19 @@ static BOOL api_WPrintJobGetInfo(connection_struct *conn,uint16 vuid, char *para
|
||||
for (i = 0; i < count; i++) {
|
||||
if (queue[i].job == job) break;
|
||||
}
|
||||
if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
|
||||
desc.base = *rdata;
|
||||
desc.buflen = mdrcnt;
|
||||
|
||||
if (mdrcnt > 0) {
|
||||
*rdata = REALLOC(*rdata,mdrcnt);
|
||||
desc.base = *rdata;
|
||||
desc.buflen = mdrcnt;
|
||||
} else {
|
||||
/*
|
||||
* Don't return data but need to get correct length
|
||||
* init_package will return wrong size if buflen=0
|
||||
*/
|
||||
desc.buflen = getlen(desc.format);
|
||||
desc.base = tmpdata = (char *)malloc ( desc.buflen );
|
||||
}
|
||||
|
||||
if (init_package(&desc,1,0)) {
|
||||
if (i < count) {
|
||||
@ -2798,6 +2833,7 @@ static BOOL api_WPrintJobGetInfo(connection_struct *conn,uint16 vuid, char *para
|
||||
SSVAL(*rparam,4,desc.neededlen);
|
||||
|
||||
if (queue) free(queue);
|
||||
if (tmpdata) free(tmpdata);
|
||||
|
||||
DEBUG(4,("WPrintJobGetInfo: errorcode %d\n",desc.errcode));
|
||||
return(True);
|
||||
@ -2932,6 +2968,7 @@ static BOOL api_WPrintDestGetInfo(connection_struct *conn,uint16 vuid, char *par
|
||||
int uLevel;
|
||||
struct pack_desc desc;
|
||||
int snum;
|
||||
char *tmpdata=NULL;
|
||||
|
||||
memset((char *)&desc,'\0',sizeof(desc));
|
||||
|
||||
@ -2959,9 +2996,18 @@ static BOOL api_WPrintDestGetInfo(connection_struct *conn,uint16 vuid, char *par
|
||||
desc.neededlen = 0;
|
||||
}
|
||||
else {
|
||||
if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
|
||||
desc.base = *rdata;
|
||||
desc.buflen = mdrcnt;
|
||||
if (mdrcnt > 0) {
|
||||
*rdata = REALLOC(*rdata,mdrcnt);
|
||||
desc.base = *rdata;
|
||||
desc.buflen = mdrcnt;
|
||||
} else {
|
||||
/*
|
||||
* Don't return data but need to get correct length
|
||||
* init_package will return wrong size if buflen=0
|
||||
*/
|
||||
desc.buflen = getlen(desc.format);
|
||||
desc.base = tmpdata = (char *)malloc ( desc.buflen );
|
||||
}
|
||||
if (init_package(&desc,1,0)) {
|
||||
fill_printdest_info(conn,snum,uLevel,&desc);
|
||||
}
|
||||
@ -2975,6 +3021,7 @@ static BOOL api_WPrintDestGetInfo(connection_struct *conn,uint16 vuid, char *par
|
||||
SSVAL(*rparam,4,desc.neededlen);
|
||||
|
||||
DEBUG(4,("WPrintDestGetInfo: errorcode %d\n",desc.errcode));
|
||||
if (tmpdata) free (tmpdata);
|
||||
return(True);
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@ extern int smb_read_error;
|
||||
extern fstring local_machine;
|
||||
extern int global_oplock_break;
|
||||
extern uint32 global_client_caps;
|
||||
extern pstring global_myname;
|
||||
|
||||
/****************************************************************************
|
||||
Send the required number of replies back.
|
||||
@ -2193,6 +2194,41 @@ static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
|
||||
return(-1);
|
||||
}
|
||||
|
||||
#define LMCAT_SPL 0x53
|
||||
#define LMFUNC_GETJOBID 0x60
|
||||
|
||||
/****************************************************************************
|
||||
reply to a TRANS2_IOCTL - used for OS/2 printing.
|
||||
****************************************************************************/
|
||||
|
||||
static int call_trans2ioctl(connection_struct *conn, char* inbuf,
|
||||
char* outbuf, int length, int bufsize,
|
||||
char** pparams, char** ppdata)
|
||||
{
|
||||
char *pdata = *ppdata;
|
||||
files_struct *fsp = file_fsp(inbuf,smb_vwv15);
|
||||
|
||||
if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
|
||||
(SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
|
||||
pdata = Realloc(*ppdata, 32);
|
||||
if(pdata == NULL) {
|
||||
return(ERROR(ERRDOS,ERRnomem));
|
||||
}
|
||||
*ppdata = pdata;
|
||||
|
||||
/* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
|
||||
CAN ACCEPT THIS IN UNICODE. JRA. */
|
||||
|
||||
SSVAL(pdata,0,fsp->print_jobid); /* Job number */
|
||||
StrnCpy(pdata+2, global_myname, 15); /* Our NetBIOS name */
|
||||
StrnCpy(pdata+18, lp_servicename(SNUM(conn)), 13); /* Service name */
|
||||
send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
|
||||
return(-1);
|
||||
} else {
|
||||
DEBUG(2,("Unknown TRANS2_IOCTL\n"));
|
||||
return(ERROR(ERRSRV,ERRerror));
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
reply to a SMBfindclose (stop trans2 directory search)
|
||||
@ -2301,9 +2337,24 @@ int reply_trans2(connection_struct *conn,
|
||||
/* All trans2 messages we handle have smb_sucnt == 1 - ensure this
|
||||
is so as a sanity check */
|
||||
if (suwcnt != 1) {
|
||||
DEBUG(2,("Invalid smb_sucnt in trans2 call\n"));
|
||||
END_PROFILE(SMBtrans2);
|
||||
return(ERROR(ERRSRV,ERRerror));
|
||||
/*
|
||||
* Need to have rc=0 for ioctl to get job id for OS/2.
|
||||
* Network printing will fail if function is not successful.
|
||||
* Similar function in reply.c will be used if protocol
|
||||
* is LANMAN1.0 instead of LM1.2X002.
|
||||
* Until DosPrintSetJobInfo with PRJINFO3 is supported,
|
||||
* outbuf doesn't have to be set(only job id is used).
|
||||
*/
|
||||
if ( (suwcnt == 4) && (tran_call == TRANSACT2_IOCTL) &&
|
||||
(SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
|
||||
(SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
|
||||
DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
|
||||
} else {
|
||||
DEBUG(2,("Invalid smb_sucnt in trans2 call(%d)\n",suwcnt));
|
||||
DEBUG(2,("Transaction is %d\n",tran_call));
|
||||
END_PROFILE(SMBtrans2);
|
||||
return(ERROR(ERRSRV,ERRerror));
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate the space for the maximum needed parameters and data */
|
||||
@ -2466,10 +2517,16 @@ int reply_trans2(connection_struct *conn,
|
||||
|
||||
case TRANSACT2_GET_DFS_REFERRAL:
|
||||
START_PROFILE_NESTED(Trans2_get_dfs_referral);
|
||||
outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length,
|
||||
bufsize, ¶ms, &data);
|
||||
outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length,
|
||||
bufsize, ¶ms, &data);
|
||||
END_PROFILE_NESTED(Trans2_get_dfs_referral);
|
||||
break;
|
||||
case TRANSACT2_IOCTL:
|
||||
START_PROFILE_NESTED(Trans2_ioctl);
|
||||
outsize = call_trans2ioctl(conn,inbuf,outbuf,length,
|
||||
bufsize,¶ms,&data);
|
||||
END_PROFILE_NESTED(Trans2_ioctl);
|
||||
break;
|
||||
default:
|
||||
/* Error in request */
|
||||
DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
|
||||
|
Loading…
x
Reference in New Issue
Block a user