Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

266 lines
7.1 KiB

//---------------------------------------------------------------------------
// prcache.c
//
// implements an Open Printer cache and Printer_ functions which use it.
//
//---------------------------------------------------------------------------
#include "shellprv.h"
#pragma hdrstop
#include "copy.h"
#ifdef WINNT
HANDLE Printer_OpenPrinterAdmin(LPCTSTR lpszPrinterName)
{
HANDLE hPrinter = NULL;
PRINTER_DEFAULTS PrinterDefaults;
PrinterDefaults.pDatatype = NULL;
PrinterDefaults.pDevMode = NULL;
PrinterDefaults.DesiredAccess = PRINTER_ALL_ACCESS;
// PRINTER_READ ? READ_CONTROL
if (!g_pfnOpenPrinter((LPTSTR)lpszPrinterName, &hPrinter, &PrinterDefaults))
{
hPrinter = NULL; // OpenPrinter may trash hPrinter
}
return(hPrinter);
}
#endif
HANDLE Printer_OpenPrinter(LPCTSTR lpszPrinterName)
{
HANDLE hPrinter = NULL;
if (!g_pfnOpenPrinter((LPTSTR)lpszPrinterName, &hPrinter, NULL))
{
hPrinter = NULL; // OpenPrinter may trash hPrinter
}
return(hPrinter);
}
VOID Printer_ClosePrinter(HANDLE hPrinter)
{
g_pfnClosePrinter(hPrinter);
}
BOOL Printers_DeletePrinter(HWND hWnd, LPCTSTR pszFullPrinter, DWORD dwAttributes,
LPCTSTR pszServer)
{
DWORD dwCommand = MSP_REMOVEPRINTER;
if (SHRestricted(REST_NOPRINTERDELETE))
{
ShellMessageBox(HINST_THISDLL, hWnd, MAKEINTRESOURCE(IDS_RESTRICTIONS),
MAKEINTRESOURCE(IDS_RESTRICTIONSTITLE), MB_OK|MB_ICONSTOP);
return(FALSE);
}
#ifdef WINNT
if (pszServer && pszServer[0])
{
Assert(pszServer[0] == TEXT('\\') && pszServer[1] == TEXT('\\'));
//
// It's a printer on the remote server. (Skip \\ prefix on server.)
//
if (ShellMessageBox(HINST_THISDLL, hWnd,
MAKEINTRESOURCE(IDS_SUREDELETEREMOTE),
MAKEINTRESOURCE(IDS_PRINTERS), MB_YESNO|MB_ICONQUESTION,
pszFullPrinter, &pszServer[2]) != IDYES)
{
return(FALSE);
}
}
else if (dwAttributes & PRINTER_ATTRIBUTE_NETWORK)
{
TCHAR szScratch[MAXNAMELENBUFFER];
LPTSTR pszPrinter;
LPTSTR pszServer;
if (!(dwAttributes & PRINTER_ATTRIBUTE_LOCAL))
{
//
// If it's not local, then it must be a remote connection. Note
// that we can't just check for PRINTER_ATTRIBUTE_NETWORK because
// NT's spooler has 'masq' printers that are local printers
// that masquarade as network printers. Even though they
// are created by connecting to a printer, the have both LOCAL
// and NETWORK bits set.
//
dwCommand = MSP_REMOVENETPRINTER;
}
Printer_SplitFullName(szScratch, pszFullPrinter, &pszServer, &pszPrinter);
Assert(pszServer[0] == TEXT('\\') && pszServer[1] == TEXT('\\'));
//
// It's a printer connection.
//
if (ShellMessageBox(HINST_THISDLL, hWnd,
MAKEINTRESOURCE(IDS_SUREDELETECONNECTION),
MAKEINTRESOURCE(IDS_PRINTERS), MB_YESNO|MB_ICONQUESTION,
pszPrinter, &pszServer[2]) != IDYES)
{
return(FALSE);
}
}
else
//
// Neither a remote printer nor a local connection. The final
// upcoming else clause is a local printer.
//
#endif
if (ShellMessageBox(HINST_THISDLL, hWnd, MAKEINTRESOURCE(IDS_SUREDELETE),
MAKEINTRESOURCE(IDS_PRINTERS), MB_YESNO|MB_ICONQUESTION, pszFullPrinter)
!= IDYES)
{
return(FALSE);
}
if (CallPrinterCopyHooks(hWnd, PO_DELETE, 0, pszFullPrinter, 0, NULL, 0)
!= IDYES)
{
return(FALSE);
}
//
// Cast away const. Safe since Printers_PrinterSetup only modifies
// pszPrinter if dwCommand is MSP_NEWDRIVER.
//
return (BOOL)Printers_PrinterSetup(hWnd, dwCommand,
(LPTSTR)pszFullPrinter, pszServer);
}
BOOL Printer_GPI2CB(LPVOID lpData, HANDLE hPrinter, DWORD dwLevel,
LPBYTE pBuf, DWORD dwSize, DWORD *lpdwNeeded, DWORD *lpdwNum)
{
return(g_pfnGetPrinter(hPrinter, dwLevel, pBuf, dwSize, lpdwNeeded));
}
#ifdef WINNT
//
// Old NT printers don't support the level 5. So we try for the 2 after 5.
// Win96 WILL PROBABLY WANT TO DO THIS TOO!
//
LPPRINTER_INFO_5 Printer_MakePrinterInfo5( HANDLE hPrinter )
{
LPPRINTER_INFO_2 pPI2;
LPPRINTER_INFO_5 pPI5;
DWORD cbPI5;
DWORD cbName;
pPI2 = Printer_EnumProps(hPrinter, 2, NULL, Printer_GPI2CB, (LPVOID)0);
if (!pPI2)
return NULL;
cbName = (lstrlen(pPI2->pPrinterName)+1) * SIZEOF(TCHAR);
cbPI5 = SIZEOF(PRINTER_INFO_5)
+ cbName;
//
// Port name may not be supported (e.g., downlevel machines).
//
if (pPI2->pPortName)
{
cbPI5 += (lstrlen(pPI2->pPortName)+1) * SIZEOF(TCHAR);
}
pPI5 = (LPPRINTER_INFO_5)LocalAlloc(LPTR, cbPI5);
if (pPI5)
{
Assert(pPI5->pPrinterName==NULL); // These should be null for the
Assert(pPI5->pPortName==NULL); // no names case
if (pPI2->pPrinterName)
{
pPI5->pPrinterName = (LPTSTR)(pPI5+1);
lstrcpy(pPI5->pPrinterName, pPI2->pPrinterName);
}
if (pPI2->pPortName)
{
pPI5->pPortName = (LPTSTR)((LPBYTE)(pPI5+1) + cbName);
lstrcpy(pPI5->pPortName, pPI2->pPortName);
}
pPI5->Attributes = pPI2->Attributes;
pPI5->DeviceNotSelectedTimeout = 0;
pPI5->TransmissionRetryTimeout = 0;
}
LocalFree(pPI2);
return(pPI5);
}
#endif
LPVOID Printer_GetPrinterInfo(HANDLE hPrinter, DWORD dwLevel)
{
LPVOID pPrinter;
pPrinter = Printer_EnumProps(hPrinter, dwLevel, NULL, Printer_GPI2CB, (LPVOID)0);
#ifdef WINNT
//
// Old NT printers don't support the level 5. So we try for the 2 after 5.
// Win96 WILL PROBABLY WANT TO DO THIS TOO!
//
if (!pPrinter && dwLevel == 5)
return(Printer_MakePrinterInfo5(hPrinter));
#endif
return pPrinter;
}
LPVOID Printer_GetPrinterInfoStr(LPCTSTR lpszPrinterName, DWORD dwLevel)
{
LPPRINTER_INFO_2 pPI2 = NULL;
HANDLE hPrinter = Printer_OpenPrinter(lpszPrinterName);
if (hPrinter)
{
pPI2 = Printer_GetPrinterInfo(hPrinter, dwLevel);
Printer_ClosePrinter(hPrinter);
}
return pPI2;
}
// Generate a SHCNE_RENAMEITEM event for this name change.
void Printer_SHChangeNotifyRename(LPTSTR pOldName, LPTSTR pNewName)
{
LPCITEMIDLIST pidlParent;
pidlParent = GetSpecialFolderIDList(NULL, CSIDL_PRINTERS, FALSE);
if (pidlParent)
{
IDPRINTER idpOld;
LPITEMIDLIST pidlOld;
Printers_FillPidl(&idpOld, pOldName);
pidlOld = ILCombine(pidlParent, (LPCITEMIDLIST)&idpOld);
if (pidlOld)
{
IDPRINTER idpNew;
LPITEMIDLIST pidlNew;
Printers_FillPidl(&idpNew, pNewName);
pidlNew = ILCombine(pidlParent, (LPCITEMIDLIST)&idpNew);
if (pidlNew)
{
SHChangeNotify(SHCNE_RENAMEITEM, SHCNF_IDLIST, pidlOld, pidlNew);
ILFree(pidlNew);
}
ILFree(pidlOld);
}
} // if (pidlParent)
}