/*++

Copyright (c) 1990 - 1996  Microsoft Corporation
All rights reserved

Module Name:

    winspool.idl

Abstract:

    A very simple interface which is part of an RPC application (client and
    server) demonstrating how to use RPC on NT.


Author:

    mikemon    12-10-90    Created.

Environment:

    User Mode -Win32

Revision History:

--*/

[
    uuid(12345678-1234-ABCD-EF00-0123456789AB),
    version(1.0),
#ifdef __midl
        ms_union,
#endif // __midl
    endpoint("mscn_np:[\\pipe\\spoolss]"),
    pointer_default(unique)
]


interface winspool
{
import   "import.idl";

#include "..\inc\ntfytab.h"

typedef WORD TABLE;

typedef struct _NOTIFY_ATTRIB_TABLE {
    WORD Attrib;
    TABLE Table;
} NOTIFY_ATTRIB_TABLE, *PNOTIFY_ATTRIB_TABLE;



typedef [context_handle] void *PRINTER_HANDLE;
typedef [context_handle] void *GDI_HANDLE;
typedef [handle] wchar_t *STRING_HANDLE;
typedef [string] wchar_t *SPL_STRING;




typedef struct _PORT_VAR_CONTAINER {
    DWORD cbMonitorData;
    [size_is(cbMonitorData), unique] LPBYTE pMonitorData;
} PORT_VAR_CONTAINER, *PPORT_VAR_CONTAINER, *LPPORT_VAR_CONTAINER;

typedef struct _PORT_CONTAINER {
    DWORD       Level;
    [switch_is(Level)] union {
        [case(1)]
             LPPORT_INFO_1W pPortInfo1;
        [case(2)]
             LPPORT_INFO_2W pPortInfo2;
        [case(3)]
             LPPORT_INFO_3W pPortInfo3;
        [case((DWORD)-1)]
             LPPORT_INFO_FFW pPortInfoFF;
    } PortInfo;

} PORT_CONTAINER, *PPORT_CONTAINER, *LPPORT_CONTAINER;

typedef struct _DEVMODE_CONTAINER {
    DWORD   cbBuf;
    [size_is(cbBuf), unique] LPBYTE pDevMode;

} DEVMODE_CONTAINER, *PDEVMODE_CONTAINER, *LPDEVMODE_CONTAINER;

typedef struct _SECURITY_CONTAINER {
    DWORD   cbBuf;
    [size_is(cbBuf), unique] LPBYTE pSecurity;

} SECURITY_CONTAINER, *PSECURITY_CONTAINER, *LPSECURITY_CONTAINER;

typedef struct _PRINTER_CONTAINER {
    DWORD   Level;
    [switch_is(Level)] union {
        [case(0)]
            LPPRINTER_INFO_STRESSW pPrinterInfoStress;
        [case(1)]
            LPPRINTER_INFO_1W pPrinterInfo1;
        [case(2)]
            LPPRINTER_INFO_2W pPrinterInfo2;
        [case(3)]
            LPPRINTER_INFO_3 pPrinterInfo3;
        [case(4)]
            LPPRINTER_INFO_4W pPrinterInfo0;
        [case(5)]
            LPPRINTER_INFO_5W pPrinterInfo5;
        [case(6)]
            LPPRINTER_INFO_6 pPrinterInfo6;
        [case(7)]
            LPPRINTER_INFO_7W pPrinterInfo7;
        [case(8)]
            LPPRINTER_INFO_8W pPrinterInfo8;
        [case(9)]
            LPPRINTER_INFO_9W pPrinterInfo9;
    } PrinterInfo;

} PRINTER_CONTAINER, *PPRINTER_CONTAINER, *LPPRINTER_CONTAINER;

typedef struct _JOB_CONTAINER {
    DWORD   Level;
    [switch_is(Level)] union {
        [case(1)]
            JOB_INFO_1W *Level1;
        [case(2)]
            JOB_INFO_2W *Level2;
        [case(3)]
            JOB_INFO_3  *Level3;
    } JobInfo;

} JOB_CONTAINER, *PJOB_CONTAINER, *LPJOB_CONTAINER;

// To handle dependentFiles field which is a list of strings
// -- MuhuntS
typedef struct _RPC_DRIVER_INFO_3W {
    DWORD       cVersion;
    SPL_STRING      pName;
    SPL_STRING      pEnvironment;
    SPL_STRING      pDriverPath;
    SPL_STRING      pDataFile;
    SPL_STRING      pConfigFile;
    SPL_STRING      pHelpFile;
    SPL_STRING      pMonitorName;
    SPL_STRING      pDefaultDataType;
    DWORD           cchDependentFiles;
    [size_is(cchDependentFiles), unique] WCHAR    *pDependentFiles;
} RPC_DRIVER_INFO_3W, *PRPC_DRIVER_INFO_3W, *LPRPC_DRIVER_INFO_3W;

typedef struct _RPC_DRIVER_INFO_4W {
    DWORD       cVersion;
    SPL_STRING      pName;
    SPL_STRING      pEnvironment;
    SPL_STRING      pDriverPath;
    SPL_STRING      pDataFile;
    SPL_STRING      pConfigFile;
    SPL_STRING      pHelpFile;
    SPL_STRING      pMonitorName;
    SPL_STRING      pDefaultDataType;
    DWORD           cchDependentFiles;
    [size_is(cchDependentFiles), unique] WCHAR    *pDependentFiles;
    DWORD           cchPreviousNames;
    [size_is(cchPreviousNames), unique] WCHAR    *pszzPreviousNames;
} RPC_DRIVER_INFO_4W, *PRPC_DRIVER_INFO_4W, *LPRPC_DRIVER_INFO_4W;

typedef struct _RPC_DRIVER_INFO_6W {
    DWORD       cVersion;
    SPL_STRING      pName;
    SPL_STRING      pEnvironment;
    SPL_STRING      pDriverPath;
    SPL_STRING      pDataFile;
    SPL_STRING      pConfigFile;
    SPL_STRING      pHelpFile;
    SPL_STRING      pMonitorName;
    SPL_STRING      pDefaultDataType;
    DWORD           cchDependentFiles;
    [size_is(cchDependentFiles), unique] WCHAR    *pDependentFiles;
    DWORD           cchPreviousNames;
    [size_is(cchPreviousNames), unique] WCHAR    *pszzPreviousNames;
    FILETIME        ftDriverDate;
    DWORDLONG       dwlDriverVersion;
    SPL_STRING      pMfgName;
    SPL_STRING      pOEMUrl;
    SPL_STRING      pHardwareID;
    SPL_STRING      pProvider;  
} RPC_DRIVER_INFO_6W, *PRPC_DRIVER_INFO_6W, *LPRPC_DRIVER_INFO_6W;

typedef struct _DRIVER_CONTAINER {
    DWORD   Level;
    [switch_is(Level)] union {
        [case(1)]
            LPDRIVER_INFO_1W Level1;
        [case(2)]
            LPDRIVER_INFO_2W Level2;
        [case(3)]
            LPRPC_DRIVER_INFO_3W Level3;
        [case(4)]
            LPRPC_DRIVER_INFO_4W Level4;
        [case(6)]
            LPRPC_DRIVER_INFO_6W Level6;        
    } DriverInfo;

} DRIVER_CONTAINER, *PDRIVER_CONTAINER, *LPDRIVER_CONTAINER;

typedef struct _RPC_DRIVER_INFCAT_INFO_1 {
    [string, ref] wchar_t *pszCatPath;
    [string, unique] wchar_t *pszCatNameOnSystem;
} RPC_DRIVER_INFCAT_INFO_1, *PRPC_DRIVER_INFCAT_INFO_1, *LPRPC_DRIVER_INFCAT_INFO_1;
   
typedef struct _RPC_DRIVER_INFCAT_INFO_2 {
    [string, ref] wchar_t *pszCatPath;
    [string, ref] wchar_t *pszInfPath;
    [string, unique] wchar_t *pszSrcLoc;
    DWORD dwMediaType;
    DWORD dwCopyStyle;
} RPC_DRIVER_INFCAT_INFO_2, *PRPC_DRIVER_INFCAT_INFO_2, *LPRPC_DRIVER_INFCAT_INFO_2;

typedef struct _DRIVER_INFCAT_CONTAINER {
    DWORD   dwLevel;
    [switch_is(dwLevel)] union {
        [case(1)]
            LPRPC_DRIVER_INFCAT_INFO_1     pDriverInfCatInfo1;
        [case(2)]
            LPRPC_DRIVER_INFCAT_INFO_2     pDriverInfCatInfo2;
    } DriverInfCatInfo;
} DRIVER_INFCAT_CONTAINER, *PDRIVER_INFCAT_CONTAINER, *LPDRIVER_INFCAT_CONTAINER;

typedef struct _DOC_INFO_CONTAINER {
    DWORD   Level;
    [switch_is(Level)] union {
        [case(1)]
            LPDOC_INFO_1W pDocInfo1;
    } DocInfo;

} DOC_INFO_CONTAINER, *PDOC_INFO_CONTAINER, *LPDOC_INFO_CONTAINER;

typedef struct _FORM_CONTAINER {
    DWORD   Level;
    [switch_is(Level)] union {
        [case(1)]
            LPFORM_INFO_1W pFormInfo1;
    } FormInfo;

} FORM_CONTAINER, *PFORM_CONTAINER, *LPFORM_CONTAINER;

typedef struct _MONITOR_CONTAINER {
    DWORD   Level;
    [switch_is(Level)] union {
        [case(1)]
            LPMONITOR_INFO_1W pMonitorInfo1;
        [case(2)]
            LPMONITOR_INFO_2W pMonitorInfo2;
    } MonitorInfo;

} MONITOR_CONTAINER, *PMONITOR_CONTAINER, *LPMONITOR_CONTAINER;

typedef struct _RPC_PROVIDOR_INFO_2W {
    DWORD           cchOrder;
    [size_is(cchOrder), unique] WCHAR    *pOrder;
    
} RPC_PROVIDOR_INFO_2W, *PRPC_PROVIDOR_INFO_2W, *LPRPC_PROVIDOR_INFO_2W;

typedef struct _PROVIDOR_CONTAINER {
    DWORD   Level;
    [switch_is(Level)] union {
        [case(1)]
            LPPROVIDOR_INFO_1W pProvidorInfo1;
        [case(2)]
            LPRPC_PROVIDOR_INFO_2W pRpcProvidorInfo2;
    } ProvidorInfo;

} PROVIDOR_CONTAINER, *PPROVIDOR_CONTAINER, *LPPROVIDOR_CONTAINER;

typedef struct _SPLCLIENT_CONTAINER {
    DWORD   Level;
    [switch_is(Level)] union {
        [case(1)]
            LPSPLCLIENT_INFO_1 pClientInfo1;
        [case(2)]
            LPSPLCLIENT_INFO_2 pClientInfo2;
    } ClientInfo;
} SPLCLIENT_CONTAINER, *PSPLCLIENT_CONTAINER, *LPSPLCLIENT_CONTAINER;

typedef struct _FILE_INFO_CONTAINER {
    DWORD   Level;
    [switch_is(Level)] union {
        [case(1)]
            SPOOL_FILE_INFO_1 *Level1;           
        [default]; 
    } FileInfo;

} FILE_INFO_CONTAINER, *PFILE_INFO_CONTAINER, *LPFILE_INFO_CONTAINER;

typedef struct _STRING_CONTAINER {
    DWORD cbBuf;
    [size_is(cbBuf/2), unique] LPWSTR pszString;
} STRING_CONTAINER, *PSTRING_CONTAINER;

typedef struct _RPC_BINARY_CONTAINER {
    DWORD cbBuf;
    [size_is(cbBuf), unique] LPBYTE pszString;
} RPC_BINARY_CONTAINER, *PRPC_BINARY_CONTAINER;

typedef struct _SYSTEMTIME_CONTAINER {
    DWORD cbBuf;
    PSYSTEMTIME pSystemTime;
} SYSTEMTIME_CONTAINER, *PSYSTEMTIME_CONTAINER;

typedef struct _RPC_V2_NOTIFY_OPTIONS_TYPE {
    WORD Type;
    WORD Reserved0;
    DWORD Reserved1;
    DWORD Reserved2;
    DWORD Count;
    [size_is(Count), unique] PWORD pFields;
} RPC_V2_NOTIFY_OPTIONS_TYPE, *PRPC_V2_NOTIFY_OPTIONS_TYPE;

typedef struct _RPC_V2_NOTIFY_OPTIONS {
    DWORD Version;
    DWORD Reserved;
    DWORD Count;
    [size_is(Count), unique] PRPC_V2_NOTIFY_OPTIONS_TYPE pTypes;
} RPC_V2_NOTIFY_OPTIONS, *PRPC_V2_NOTIFY_OPTIONS;



typedef [switch_type(DWORD)] union _RPC_V2_NOTIFY_INFO_DATA_DATA {
    [case(TABLE_STRING)]
        STRING_CONTAINER String;
    [case(TABLE_DWORD)]
        DWORD dwData[2];
    [case(TABLE_TIME)]
        SYSTEMTIME_CONTAINER SystemTime;
    [case(TABLE_DEVMODE)]
        DEVMODE_CONTAINER DevMode;
    [case(TABLE_SECURITYDESCRIPTOR)]
        SECURITY_CONTAINER SecurityDescriptor;
} RPC_V2_NOTIFY_INFO_DATA_DATA, *PRPC_V2_NOTIFY_INFO_DATA_DATA;


typedef struct _RPC_V2_NOTIFY_INFO_DATA {
    WORD Type;
    WORD Field;
    DWORD Reserved;
    DWORD Id;
    [switch_is(Reserved & 0xffff)] RPC_V2_NOTIFY_INFO_DATA_DATA Data;
} RPC_V2_NOTIFY_INFO_DATA, *PRPC_V2_NOTIFY_INFO_DATA;

typedef struct _RPC_V2_NOTIFY_INFO {
    DWORD Version;
    DWORD Flags;
    DWORD Count;
    [size_is(Count), unique] RPC_V2_NOTIFY_INFO_DATA aData[];
} RPC_V2_NOTIFY_INFO, *PRPC_V2_NOTIFY_INFO;


typedef [switch_type(DWORD)] union _RPC_V2_UREPLY_PRINTER {
    [case (REPLY_PRINTER_CHANGE)]
        PRPC_V2_NOTIFY_INFO pInfo;
} RPC_V2_UREPLY_PRINTER, *PRPC_V2_UREPLY_PRINTER;



DWORD
RpcEnumPrinters(
   [in] DWORD Flags,
   [in, string, unique]  STRING_HANDLE Name,
   [in] DWORD Level,
   [in, out, unique, size_is(cbBuf)] LPBYTE   pPrinterEnum,
   [in]  DWORD    cbBuf,
   [out] LPDWORD  pcbNeeded,
   [out] LPDWORD  pcReturned
);

DWORD
RpcOpenPrinter(
   [in, string, unique] STRING_HANDLE pPrinterName,
   [out] PRINTER_HANDLE *pHandle,
   [in, string, unique] wchar_t * pDatatype,
   [in] LPDEVMODE_CONTAINER pDevMode,
   [in] DWORD AccessRequired
);

DWORD
RpcSetJob(
    [in] PRINTER_HANDLE  hPrinter,
    [in] DWORD  JobId,
    [in, unique] LPJOB_CONTAINER pJobContainer,
    [in] DWORD  Command
);

DWORD
RpcGetJob(
   [in] PRINTER_HANDLE hPrinter,
   [in] DWORD JobId,
   [in] DWORD Level,
   [in, out, unique, size_is(cbBuf)] LPBYTE pJob,
   [in] DWORD cbBuf,
   [out] LPDWORD pcbNeeded
);

DWORD
RpcEnumJobs(
   [in] PRINTER_HANDLE hPrinter,
   [in] DWORD FirstJob,
   [in] DWORD NoJobs,
   [in] DWORD Level,
   [in, out, unique, size_is(cbBuf)] LPBYTE pJob,
   [in] DWORD cbBuf,
   [out] LPDWORD pcbNeeded,
   [out] LPDWORD pcReturned
);

DWORD
RpcAddPrinter(
   [in, string, unique] STRING_HANDLE pName,
   [in] PPRINTER_CONTAINER pPrinterContainer,
   [in] PDEVMODE_CONTAINER pDevModeContainer,
   [in] PSECURITY_CONTAINER pSecurityContainer,
   [out] PRINTER_HANDLE *pHandle
);

DWORD
RpcDeletePrinter(
   [in] PRINTER_HANDLE hPrinter
);

DWORD
RpcSetPrinter(
   [in] PRINTER_HANDLE hPrinter,
   [in] PPRINTER_CONTAINER pPrinterContainer,
   [in] PDEVMODE_CONTAINER pDevModeContainer,
   [in] PSECURITY_CONTAINER pSecurityContainer,
   [in] DWORD Command
);

DWORD
RpcGetPrinter(
    [in] PRINTER_HANDLE hPrinter,
    [in] DWORD Level,
    [in, out, unique, size_is(cbBuf)] LPBYTE pPrinter,
    [in] DWORD cbBuf,
    [out] LPDWORD pcbNeeded
    );

DWORD
RpcAddPrinterDriver(
   [in, string, unique] STRING_HANDLE pName,
   [in] PDRIVER_CONTAINER pDriverContainer
);

DWORD
RpcEnumPrinterDrivers(
   [in, string, unique] STRING_HANDLE pName,
   [in, unique, string] wchar_t * pEnvironment,
   [in] DWORD Level,
   [in, out, unique, size_is(cbBuf)] LPBYTE pDrivers,
   [in] DWORD cbBuf,
   [out] LPDWORD pcbNeeded,
   [out] LPDWORD pcReturned
);

DWORD
RpcGetPrinterDriver(
   [in] PRINTER_HANDLE hPrinter,
   [in, unique, string] wchar_t * pEnvironment,
   [in] DWORD Level,
   [in, out, unique, size_is(cbBuf)] LPBYTE pDriver,
   [in] DWORD cbBuf,
   [out] LPDWORD pcbNeeded
);

DWORD
RpcGetPrinterDriverDirectory(
    [in, string, unique] STRING_HANDLE  pName,
    [in, unique, string] wchar_t *  pEnvironment,
    [in] DWORD   Level,
    [in, out, unique, size_is(cbBuf)] LPBYTE  pDriverDirectory,
    [in] DWORD   cbBuf,
    [out] LPDWORD pcbNeeded
);

DWORD
RpcDeletePrinterDriver(
   [in, string, unique] STRING_HANDLE   pName,
   [in, string] wchar_t *   pEnvironment,
   [in, string] wchar_t *   pDriverName
);

DWORD
RpcAddPrintProcessor(
   [in, string, unique] STRING_HANDLE pName,
   [in, string] wchar_t * pEnvironment,
   [in, string] wchar_t * pPathName,
   [in, string] wchar_t * pPrintProcessorName
);

DWORD
RpcEnumPrintProcessors(
   [in, string, unique] STRING_HANDLE pName,
   [in, unique, string] wchar_t * pEnvironment,
   [in] DWORD Level,
   [in, out, unique, size_is(cbBuf)] LPBYTE pPrintProcessorInfo,
   [in] DWORD cbBuf,
   [out] LPDWORD pcbNeeded,
   [out] LPDWORD pcReturned
);

DWORD
RpcGetPrintProcessorDirectory(
    [in, string, unique] STRING_HANDLE  pName,
    [in, unique, string] wchar_t *  pEnvironment,
    [in] DWORD   Level,
    [in, out, unique, size_is(cbBuf)] LPBYTE  pPrintProcessorDirectory,
    [in] DWORD   cbBuf,
    [out] LPDWORD pcbNeeded
);

DWORD
RpcStartDocPrinter(
   [in] PRINTER_HANDLE hPrinter,
   [in] PDOC_INFO_CONTAINER     pDocInfoContainer,
   [out] LPDWORD pJobId
);

DWORD
RpcStartPagePrinter(
   [in] PRINTER_HANDLE   hPrinter
);

DWORD
RpcWritePrinter(
   [in] PRINTER_HANDLE hPrinter,
   [in, size_is(cbBuf)] LPBYTE pBuf,
   [in] DWORD cbBuf,
   [out] LPDWORD pcWritten
);

DWORD
RpcEndPagePrinter(
   [in] PRINTER_HANDLE hPrinter
);

DWORD
RpcAbortPrinter(
   [in] PRINTER_HANDLE hPrinter
);

DWORD
RpcReadPrinter(
   [in] PRINTER_HANDLE hPrinter,
   [out, size_is(cbBuf)] LPBYTE pBuf,
   [in] DWORD cbBuf,
   [out] LPDWORD pcNoBytesRead
);

DWORD
RpcEndDocPrinter(
   [in] PRINTER_HANDLE hPrinter
);

DWORD
RpcAddJob(
    [in] PRINTER_HANDLE  hPrinter,
    [in] DWORD   Level,
    [in, out, unique, size_is(cbBuf)] LPBYTE pAddJob,
    [in] DWORD   cbBuf,
    [out] LPDWORD pcbNeeded
);

DWORD
RpcScheduleJob(
    [in] PRINTER_HANDLE  hPrinter,
    [in] DWORD   JobId
);

DWORD
RpcGetPrinterData(
    [in] PRINTER_HANDLE hPrinter,
    [in, string] wchar_t * pValueName,
    [out] LPDWORD pType,
    [out, size_is(nSize)] LPBYTE pData,
    [in] DWORD nSize,
    [out] LPDWORD pcbNeeded
);

DWORD
RpcSetPrinterData(
    [in] PRINTER_HANDLE hPrinter,
    [in, string] wchar_t *  pValueName,
    [in] DWORD  Type,
    [in, size_is(cbData)] LPBYTE pData,
    [in] DWORD  cbData
);

DWORD
RpcWaitForPrinterChange(
   [in] PRINTER_HANDLE hPrinter,
   [in] DWORD Flags,
   [out] LPDWORD pFlags
);

DWORD
RpcClosePrinter(
   [in, out] PRINTER_HANDLE *phPrinter
);

DWORD
RpcAddForm(
    [in] PRINTER_HANDLE hPrinter,
    [in] PFORM_CONTAINER pFormInfoContainer
);

DWORD
RpcDeleteForm(
    [in] PRINTER_HANDLE  hPrinter,
    [in, string] wchar_t *   pFormName
);

DWORD
RpcGetForm(
    [in] PRINTER_HANDLE  hPrinter,
    [in, string] wchar_t * pFormName,
    [in] DWORD Level,
    [in, out, unique, size_is(cbBuf)] LPBYTE pForm,
    [in] DWORD cbBuf,
    [out] LPDWORD pcbNeeded
);

DWORD
RpcSetForm(
    [in] PRINTER_HANDLE hPrinter,
    [in, string] wchar_t * pFormName,
    [in] PFORM_CONTAINER pFormInfoContainer
);

DWORD
RpcEnumForms(
   [in] PRINTER_HANDLE hPrinter,
   [in] DWORD Level,
   [in, out, unique, size_is(cbBuf)] LPBYTE   pForm,
   [in]  DWORD    cbBuf,
   [out] LPDWORD  pcbNeeded,
   [out] LPDWORD  pcReturned
);

DWORD
RpcEnumPorts(
   [in, string, unique] STRING_HANDLE pName,
   [in] DWORD Level,
   [in, out, unique, size_is(cbBuf)] LPBYTE   pPort,
   [in]  DWORD    cbBuf,
   [out] LPDWORD  pcbNeeded,
   [out] LPDWORD  pcReturned
);

DWORD
RpcEnumMonitors(
   [in, string, unique] STRING_HANDLE pName,
   [in] DWORD Level,
   [in, out, unique, size_is(cbBuf)] LPBYTE   pMonitor,
   [in]  DWORD    cbBuf,
   [out] LPDWORD  pcbNeeded,
   [out] LPDWORD  pcReturned
);

DWORD
RpcAddPort(
   [in, string, unique] STRING_HANDLE pName,
   [in] ULONG_PTR hWnd,
   [in, string] wchar_t * pMonitorName
);

DWORD
RpcConfigurePort(
   [in, string, unique] STRING_HANDLE pName,
   [in] ULONG_PTR hWnd,
   [in, string] wchar_t * pPortName
);

DWORD
RpcDeletePort(
   [in, string, unique] STRING_HANDLE pName,
   [in] ULONG_PTR hWnd,
   [in, string] wchar_t * pPortName
);

DWORD
RpcCreatePrinterIC(
   [in] PRINTER_HANDLE hPrinter,
   [out] GDI_HANDLE *pHandle,
   [in] LPDEVMODE_CONTAINER pDevModeContainer
);

DWORD
RpcPlayGdiScriptOnPrinterIC(
    [in] GDI_HANDLE  hPrinterIC,
    [in, size_is(cIn)] LPBYTE pIn,
    [in] DWORD   cIn,
    [out, size_is(cOut)] LPBYTE pOut,
    [in] DWORD   cOut,
    [in] DWORD   ul
);

DWORD
RpcDeletePrinterIC(
    [in, out] GDI_HANDLE *phPrinterIC
);

DWORD
RpcAddPrinterConnection(
   [in, string] STRING_HANDLE pName
);

DWORD
RpcDeletePrinterConnection(
   [in, string] STRING_HANDLE pName
);

DWORD
RpcPrinterMessageBox(
   [in] PRINTER_HANDLE hPrinter,
   [in] DWORD          Error,
   [in] ULONG_PTR      hWnd,
   [in, string, unique] wchar_t *pText,
   [in, string, unique] wchar_t *pCaption,
   [in] DWORD   dwType
);

DWORD
RpcAddMonitor(
   [in, string, unique] STRING_HANDLE Name,
   [in] PMONITOR_CONTAINER pMonitorContainer
);

DWORD
RpcDeleteMonitor(
   [in, string, unique] STRING_HANDLE Name,
   [in, unique, string] wchar_t * pEnvironment,
   [in, string] wchar_t *pMonitorName
);

DWORD
RpcDeletePrintProcessor(
   [in, string, unique] STRING_HANDLE Name,
   [in, unique, string] wchar_t * pEnvironment,
   [in, string] wchar_t *pPrintProcessorName
);

DWORD
RpcAddPrintProvidor(
   [in, string, unique] STRING_HANDLE Name,
   [in] PPROVIDOR_CONTAINER pProvidorContainer
);

DWORD
RpcDeletePrintProvidor(
   [in, string, unique] STRING_HANDLE Name,
   [in, unique, string] wchar_t * pEnvironment,
   [in, string] wchar_t *pPrintProvidorName
);

DWORD
RpcEnumPrintProcessorDatatypes(
   [in, string, unique] STRING_HANDLE pName,
   [in, unique, string] wchar_t * pPrintProcessorName,
   [in] DWORD Level,
   [in, out, unique, size_is(cbBuf)] LPBYTE   pDatatypes,
   [in]  DWORD    cbBuf,
   [out] LPDWORD  pcbNeeded,
   [out] LPDWORD  pcReturned
);

DWORD
RpcResetPrinter(
   [in] PRINTER_HANDLE hPrinter,
   [in, string, unique] wchar_t * pDatatype,
   [in] LPDEVMODE_CONTAINER pDevMode
);

//
// Everything below is new to the interface (new for daytona).
//

DWORD
RpcGetPrinterDriver2(
   [in] PRINTER_HANDLE hPrinter,
   [in, unique, string] wchar_t * pEnvironment,
   [in] DWORD Level,
   [in, out, unique, size_is(cbBuf)] LPBYTE pDriver,
   [in] DWORD cbBuf,
   [out] LPDWORD pcbNeeded,
   [in] DWORD dwClientMajorVersion,
   [in] DWORD dwClientMinorVersion,
   [out] LPDWORD pdwServerMaxVersion,
   [out] LPDWORD pdwServerMinVersion
);

DWORD
RpcClientFindFirstPrinterChangeNotification(
   [in] PRINTER_HANDLE hPrinter,
   [in] DWORD fdwFlags,
   [in] DWORD fdwOptions,
   [in] DWORD dwPID,
   [in, unique] PRPC_V2_NOTIFY_OPTIONS pOptions,
   [out] LPDWORD pdwEvent
);


DWORD
RpcFindNextPrinterChangeNotification(
   [in] PRINTER_HANDLE hPrinter,
   [in] DWORD fdwFlags,
   [out] LPDWORD pdwChange,
   [in, unique] PRPC_V2_NOTIFY_OPTIONS pOptions,
   [out] PRPC_V2_NOTIFY_INFO* ppInfo
);

DWORD
RpcFindClosePrinterChangeNotification(
   [in] PRINTER_HANDLE hPrinter
);


//
// This func will never be used (only be beta2 daytona)
//
DWORD
RpcRouterFindFirstPrinterChangeNotificationOld(
   [in] PRINTER_HANDLE hPrinter,
   [in] DWORD fdwFlags,
   [in] DWORD fdwOptions,
   [in, string, unique] wchar_t * pszLocalMachine,
   [in] DWORD dwPrinterLocal
);


//
// The following calls:
//
// RpcReplyPrinterOpenChangeNotification
// RpcReplyPrinterChangeNotification
// RpcReplyPrinterCloseChangeNotification
//
// Originate from the printserver's spooler and go the the client
// machine for notifications.
//
DWORD
RpcReplyOpenPrinter(
   [in, string] STRING_HANDLE pMachine,
   [out] PRINTER_HANDLE *phPrinterNotify,
   [in] DWORD dwPrinterRemote,
   [in] DWORD dwType,
   [in] DWORD cbBuffer,
   [in, unique, size_is(cbBuffer)] LPBYTE pBuffer
);

DWORD
RpcRouterReplyPrinter(
   [in] PRINTER_HANDLE hNotify,
   [in] DWORD fdwFlags,
   [in] DWORD cbBuffer,
   [in, unique, size_is(cbBuffer)] LPBYTE pBuffer
);

DWORD
RpcReplyClosePrinter(
   [in, out] PRINTER_HANDLE *phNotify
);

DWORD
RpcAddPortEx(
    [in, string, unique] STRING_HANDLE pName,
    [in] LPPORT_CONTAINER pPortContainer,
    [in] LPPORT_VAR_CONTAINER pPortVarContainer,
    [in, string] wchar_t * pMonitorName
);

DWORD
RpcRemoteFindFirstPrinterChangeNotification(
   [in] PRINTER_HANDLE hPrinter,
   [in] DWORD fdwFlags,
   [in] DWORD fdwOptions,
   [in, string, unique] wchar_t * pszLocalMachine,
   [in] DWORD dwPrinterLocal,
   [in] DWORD cbBuffer,
   [in, out, unique, size_is(cbBuffer)] LPBYTE pBuffer
);

DWORD
RpcSpoolerInit(
   [in] STRING_HANDLE pName
);


DWORD
RpcResetPrinterEx(
   [in] PRINTER_HANDLE hPrinter,
   [in, string, unique] wchar_t * pDatatype,
   [in] LPDEVMODE_CONTAINER pDevMode,
   [in] DWORD dwFlags
);


//
// The following calls are new for PPC release NT 3.51
//

DWORD
RpcRemoteFindFirstPrinterChangeNotificationEx(
   [in] PRINTER_HANDLE hPrinter,
   [in] DWORD fdwFlags,
   [in] DWORD fdwOptions,
   [in, string, unique] wchar_t * pszLocalMachine,
   [in] DWORD dwPrinterLocal,
   [in, unique] PRPC_V2_NOTIFY_OPTIONS pOptions
);

DWORD
RpcRouterReplyPrinterEx(
   [in] PRINTER_HANDLE hNotify,
   [in] DWORD dwColor,
   [in] DWORD fdwFlags,
   [out] PDWORD pdwResult,
   [in] DWORD dwReplyType,
   [in, switch_is(dwReplyType)] RPC_V2_UREPLY_PRINTER Reply
);

DWORD
RpcRouterRefreshPrinterChangeNotification(
   [in] PRINTER_HANDLE hPrinter,
   [in] DWORD dwColor,
   [in, unique] PRPC_V2_NOTIFY_OPTIONS pOptions,
   [out] PRPC_V2_NOTIFY_INFO* ppInfo
);

// Testing Apis for PPC

DWORD
RpcSetAllocFailCount(
    [in] PRINTER_HANDLE hPrinter,
    [in] DWORD   dwFailCount,
    [out] LPDWORD lpdwAllocCount,
    [out] LPDWORD lpdwFreeCount,
    [out] LPDWORD lpdwFailCountHit
);

// New for SUR beta NT 4.0

DWORD
RpcOpenPrinterEx(
   [in, string, unique] STRING_HANDLE pPrinterName,
   [out] PRINTER_HANDLE *pHandle,
   [in, string, unique] wchar_t * pDatatype,
   [in] LPDEVMODE_CONTAINER pDevMode,
   [in] DWORD AccessRequired,
   [in] PSPLCLIENT_CONTAINER pClientInfo
);

DWORD
RpcAddPrinterEx(
   [in, string, unique] STRING_HANDLE pName,
   [in] PPRINTER_CONTAINER pPrinterContainer,
   [in] PDEVMODE_CONTAINER pDevModeContainer,
   [in] PSECURITY_CONTAINER pSecurityContainer,
   [in] PSPLCLIENT_CONTAINER pClientInfo,
   [out] PRINTER_HANDLE *pHandle
);

DWORD
RpcSetPort(
    [in, string, unique] STRING_HANDLE pName,
    [in, string, unique] wchar_t * pPortName,
    [in] LPPORT_CONTAINER pPortContainer
);

DWORD
RpcEnumPrinterData(
    [in] PRINTER_HANDLE hPrinter,
    [in] DWORD dwIndex,
    [out, size_is(cbValueName/sizeof(wchar_t))] wchar_t * pValueName,
    [in]  DWORD cbValueName,
    [out] LPDWORD pcbValueName,
    [out] LPDWORD pType,
    [out, size_is(cbData)] LPBYTE pData,
    [in]  DWORD cbData,
    [out] LPDWORD pcbData
);

DWORD
RpcDeletePrinterData(
    [in] PRINTER_HANDLE hPrinter,
    [in, string] wchar_t * pValueName
);

//
// New for clustering
//
DWORD
RpcClusterSplOpen(
    [in, string, unique] STRING_HANDLE pServerName,
    [in, string, unique] wchar_t * pResource,
    [out] PRINTER_HANDLE *pHandle,
    [in, string, unique] wchar_t * pName,
    [in, string, unique] wchar_t * pAddress
);

DWORD
RpcClusterSplClose(
    [in, out] PRINTER_HANDLE * phPrinter
);

DWORD
RpcClusterSplIsAlive(
    [in] PRINTER_HANDLE hPrinter
);


DWORD
RpcSetPrinterDataEx(
    [in] PRINTER_HANDLE hPrinter,
    [in, string] const wchar_t *  pKeyName,
    [in, string] const wchar_t *  pValueName,
    [in] DWORD  Type,
    [in, size_is(cbData)] LPBYTE pData,
    [in] DWORD  cbData
);

DWORD
RpcGetPrinterDataEx(
    [in] PRINTER_HANDLE hPrinter,
    [in, string] const wchar_t * pKeyName,
    [in, string] const wchar_t * pValueName,
    [out] LPDWORD pType,
    [out, size_is(nSize)] LPBYTE pData,
    [in] DWORD nSize,
    [out] LPDWORD pcbNeeded
);


DWORD
RpcEnumPrinterDataEx(
    [in]  PRINTER_HANDLE hPrinter,
    [in, string]  const wchar_t * pKeyName,
    [out, size_is(cbEnumValues)] LPBYTE pEnumValues,
    [in]  DWORD cbEnumValues,
    [out] LPDWORD pcbEnumValues,
    [out] LPDWORD pnEnumValues
);

DWORD
RpcEnumPrinterKey(
    [in] PRINTER_HANDLE hPrinter,
    [in, string] const wchar_t * pKeyName,
    [out, size_is(cbSubkey/sizeof(wchar_t))] wchar_t * pSubkey,
    [in]  DWORD cbSubkey,
    [out] LPDWORD pcbSubkey
);

DWORD
RpcDeletePrinterDataEx(
    [in] PRINTER_HANDLE hPrinter,
    [in, string] const wchar_t * pKeyName,
    [in, string] const wchar_t * pValueName
);


DWORD
RpcDeletePrinterKey(
    [in] PRINTER_HANDLE hPrinter,
    [in, string] const wchar_t * pKeyName
);

DWORD
RpcSeekPrinter(
    [in] PRINTER_HANDLE hPrinter,
    [in] LARGE_INTEGER liDistanceToMove,
    [out] PLARGE_INTEGER pliNewPointer,
    [in] DWORD dwMoveMethod,
    [in] BOOL bWrite
);

DWORD
RpcDeletePrinterDriverEx(
    [in, string, unique] STRING_HANDLE pName,
    [in, string] wchar_t *pEnvironment,
    [in, string] wchar_t *pDriverName,
    [in] DWORD dwDeleteFlag,
    [in] DWORD dwVersionNum
);

DWORD
RpcAddPerMachineConnection(
   [in, string, unique] STRING_HANDLE pServer,
   [in, string] const wchar_t *  pPrinterName,
   [in, string] const wchar_t *  pPrintServer,
   [in, string] const wchar_t *  pProvider
);

DWORD
RpcDeletePerMachineConnection(
   [in, string, unique] STRING_HANDLE pServer,
   [in, string] const wchar_t *  pPrinterName
);

DWORD
RpcEnumPerMachineConnections(
   [in, string, unique]  STRING_HANDLE pServer,
   [in, out, unique, size_is(cbBuf)] LPBYTE   pPrinterEnum,
   [in]  DWORD    cbBuf,
   [out] LPDWORD  pcbNeeded,
   [out] LPDWORD  pcReturned
);

DWORD
RpcXcvData(
    [in] PRINTER_HANDLE hXcv,
    [in, string]  const wchar_t *pszDataName,
    [in, size_is(cbInputData)] PBYTE pInputData,
    [in] DWORD cbInputData,
    [out, size_is(cbOutputData)] PBYTE pOutputData,
    [in] DWORD cbOutputData,
    [out] PDWORD pcbOutputNeeded,
    [in, out] PDWORD pdwStatus
);

DWORD
RpcAddPrinterDriverEx(
   [in, string, unique] STRING_HANDLE pName,
   [in] PDRIVER_CONTAINER pDriverContainer,
   [in] DWORD dwFileCopyFlags
);

// Private Spooler interface to return the server side hPrinter to the client

DWORD
RpcSplOpenPrinter(
   [in, string, unique] STRING_HANDLE pPrinterName,
   [out] PRINTER_HANDLE *pHandle,
   [in, string, unique] wchar_t * pDatatype,
   [in] LPDEVMODE_CONTAINER pDevMode,
   [in] DWORD AccessRequired,
   [in, out] PSPLCLIENT_CONTAINER pSplClientContainer
);

DWORD
RpcGetSpoolFileInfo(
   [in] PRINTER_HANDLE hPrinter,
   [in] DWORD dwAppProcessId,
   [in] DWORD dwLevel,
   [out, size_is(cbBuf)] LPBYTE pSpoolFileInfo,
   [in] DWORD cbBuf,
   [out] LPDWORD pcbNeeded
);


DWORD
RpcCommitSpoolData(
   [in] PRINTER_HANDLE hPrinter,
   [in] DWORD dwAppProcessId,   
   [in] DWORD cbCommit,
   [in] DWORD dwLevel,
   [out, size_is(cbBuf)] LPBYTE pSpoolFileInfo,
   [in] DWORD cbBuf,
   [out] LPDWORD pcbNeeded
);

DWORD
RpcGetSpoolFileInfo2(
   [in] PRINTER_HANDLE hPrinter,
   [in] DWORD dwAppProcessId,
   [in] DWORD dwLevel,
   [in,out] LPFILE_INFO_CONTAINER pSplFileInfoContainer
);

DWORD
RpcCommitSpoolData2(
   [in] PRINTER_HANDLE hPrinter,
   [in] DWORD dwAppProcessId,   
   [in] DWORD cbCommit,
   [in] DWORD dwLevel,
   [in,out] LPFILE_INFO_CONTAINER pSplFileInfoContainer
);

DWORD
RpcCloseSpoolFileHandle(
   [in] PRINTER_HANDLE hPrinter
);

DWORD
RpcFlushPrinter(
   [in] PRINTER_HANDLE hPrinter,
   [in, size_is(cbBuf)] LPBYTE pBuf,
   [in] DWORD cbBuf,
   [out] LPDWORD pcWritten,
   [in] DWORD cSleep
);

typedef struct _RPC_BIDI_DATA
{
    DWORD dwBidiType; 
    [switch_is(dwBidiType)] union {
    [case(BIDI_NULL, BIDI_BOOL)]
        BOOL bData;
    [case(BIDI_INT)]
        LONG iData;
    [case(BIDI_STRING, BIDI_TEXT, BIDI_ENUM)]
        [string,unique] wchar_t* sData;
    [case(BIDI_FLOAT)]
        FLOAT fData;
    [case(BIDI_BLOB)]
        RPC_BINARY_CONTAINER biData;    
    } u;
} RPC_BIDI_DATA, *PRPC_BIDI_DATA, *LPRPC_BIDI_DATA;
    
typedef struct _RPC_BIDI_REQUEST_DATA {
    DWORD dwReqNumber;
    [string,unique] wchar_t* pSchema;
    RPC_BIDI_DATA data;
} RPC_BIDI_REQUEST_DATA, *PRPC_BIDI_REQUEST_DATA, *LPRPC_BIDI_REQUEST_DATA;

typedef struct _RPC_BIDI_REQUEST_CONTAINER {
    DWORD Version;
    DWORD Flags;
    DWORD Count;
    [size_is(Count), unique] RPC_BIDI_REQUEST_DATA aData[];
} RPC_BIDI_REQUEST_CONTAINER, *PRPC_BIDI_REQUEST_CONTAINER, *LPRPC_BIDI_REQUEST_CONTAINER;


typedef struct _RPC_BIDI_RESPONSE_DATA {
    DWORD dwResult;
    DWORD dwReqNumber;
    [string,unique] wchar_t* pSchema;
    RPC_BIDI_DATA data;
} RPC_BIDI_RESPONSE_DATA, *PRPC_BIDI_RESPONSE_DATA, *LPRPC_BIDI_RESPONSE_DATA;

typedef struct _RPC_BIDI_RESPONSE_CONTAINER {
    DWORD Version;
    DWORD Flags;
    DWORD Count;
    [size_is(Count), unique] RPC_BIDI_RESPONSE_DATA aData[];
} RPC_BIDI_RESPONSE_CONTAINER, *PRPC_BIDI_RESPONSE_CONTAINER, *LPRPC_BIDI_RESPONSE_CONTAINER;


DWORD RpcSendRecvBidiData (
    [in] PRINTER_HANDLE hPrinter,
    [in,string,unique] const wchar_t *pAction,
    [in] PRPC_BIDI_REQUEST_CONTAINER pReqData,
    [out] PRPC_BIDI_RESPONSE_CONTAINER *ppRespData);

DWORD RpcAddDriverCatalog(
   [in] PRINTER_HANDLE hPrinter,
   [in] PDRIVER_INFCAT_CONTAINER pDriverInfCatContainer,
   [in] DWORD dwCatalogCopyFlags);
}



