Example #1
0
LPTSTR
GetErrorString(
    DWORD   Error
)
{
    TCHAR   Buffer[1024];
    LPTSTR  pErrorString = NULL;
    DWORD   dwFlags;
    HANDLE  hModule;

    if ((Error >= NERR_BASE) && (Error <= MAX_NERR)){
        hModule = LoadLibrary(TEXT("NETMSG.DLL"));
        dwFlags = FORMAT_MESSAGE_FROM_HMODULE;
    }
    else {
        hModule = NULL;
        dwFlags = FORMAT_MESSAGE_FROM_SYSTEM;
    }

    if( FormatMessage( dwFlags, hModule,
                       Error, 0, Buffer,
                       sizeof(Buffer)/sizeof(Buffer[0]), NULL )
      == 0 )

        LoadString( hInst, IDS_UNKNOWN_ERROR, Buffer, sizeof(Buffer)/sizeof(Buffer[0]));

    pErrorString = AllocSplStr(Buffer);

    if (hModule) {
        FreeLibrary(hModule);
    }

    return pErrorString;
}
Example #2
0
LPTSTR Make8dot3Name( LPTSTR pSourceName )
{
    LPTSTR p, pName;
    TCHAR NameBuffer[MAX_PRINTER_NAME_LEN+MAX_SHARE_NAME_LEN+1];
    LPTSTR p8dot3Name = NULL;

    pName = pSourceName;

    /* Skip initial blanks:
     */
    while( *pName && ( *pName == SPACE ) )
        pName++;

    /* Skip over all backslashes:
     */
    if( p = _tcsrchr( pName, BACKSLASH ) )
    {
        /* If there's another character after the backslash,
         * make that the first character of the name:
         */
        if( *(p+1) )
        {
            pName = p+1;
        }

        /* Try to find another string before the backslash:
         */
        else
        {
            /* Back through any backslashes at the end of the name:
             */
            while( ( *p == BACKSLASH ) && ( p > pName ) )
                p--;

            /* Back up to any preceding backslash or the beginning
             * of the name:
             */
            while( ( *p != BACKSLASH ) && ( p > pName ) )
                p--;

            if( *p == BACKSLASH )
                p++;

            pName = p;
        }
    }

    /* Copy the complete name:
     */
    _tcscpy( NameBuffer, pName );

    StripBlanks( NameBuffer );

    NameBuffer[8] = NULLC;

    FreeSplStr( pSourceName );
    return AllocSplStr( NameBuffer );
}
Example #3
0
BOOL
ReallocSplStr(
   LPTSTR *plpStr,
   LPTSTR lpStr
)
{
   FreeSplStr(*plpStr);
   *plpStr=AllocSplStr(lpStr);

   return TRUE;
}
Example #4
0
BOOL
ReallocSplStr(
    LPWSTR *ppStr,
    LPWSTR pStr
    )
{
    LPWSTR pOldStr = *ppStr;

    *ppStr = AllocSplStr(pStr);
    FreeSplStr(pOldStr);

    if ( *ppStr == NULL && pStr != NULL ) {
        return FALSE;
    }
    return TRUE;
}
Example #5
0
BOOL
StartDocPort(
    HANDLE  hPort,
    LPWSTR   pPrinterName,
    DWORD   JobId,
    DWORD   Level,
    LPBYTE  pDocInfo
)
{
    PINIPORT    pIniPort = (PINIPORT)hPort;
    LPWSTR       pFileName;

    pIniPort->hFile = INVALID_HANDLE_VALUE;

   EnterSplSem();

    if (pIniPort->pPrinterName = AllocSplStr(pPrinterName)) {
        if (OpenPrinter(pPrinterName, &pIniPort->hPrinter, NULL)) {

            pIniPort->JobId = JobId;

            pFileName = pIniPort->pName;

            pIniPort->hFile = CreateFile(pFileName, GENERIC_WRITE,
                                         FILE_SHARE_READ, NULL, OPEN_ALWAYS,
                                         FILE_ATTRIBUTE_NORMAL, NULL);
        } else
            FreeSplStr(pIniPort->pPrinterName);

    }

   LeaveSplSem();

    if (pIniPort->hFile == INVALID_HANDLE_VALUE) {
//     DbgPrint("localmon!StartDocPort FAILED %x\n", GetLastError());
        return FALSE;
    } else {
        return TRUE;
    }
}
Example #6
0
/*++

Routine Name:

    PortNameCommandOK

Routine Description:

    Handles the case when the user clicks ok on the port name dialog

Arguments:

    hDlg    - handle to dialog

Return Value:

    TRUE success, FALSE an error occurred.

--*/
BOOL
PortNameCommandOK(
    HWND    hwnd
    )
{
    PPORTDIALOG pPort;
    WCHAR   string [MAX_LOCAL_PORTNAME + 1] = L"";
    WCHAR   trimmedString [MAX_LOCAL_PORTNAME + 1] = L"";
    WCHAR   szWideSpace[] = L" ";
    BOOL    rc;
    DWORD   cbNeeded;
    DWORD   dwStatus = NO_ERROR;
    DWORD   indexString = 0;
    DWORD   indexTrimmedString = 0;
    SHORT   end;
    size_t  cbSize = 0;

    if ((pPort = (PPORTDIALOG) GetWindowLongPtr( hwnd, GWLP_USERDATA )) == NULL)
    {
        dwStatus = ERROR_INVALID_DATA;
        ErrorMessage (hwnd, dwStatus);
        SetLastError (dwStatus);
        return FALSE;
    }

    GetDlgItemText( hwnd, IDD_PN_EF_PORTNAME, string, COUNTOF(string));
    string [COUNTOF (string) - 1] = L'\0';

    //
    // Trim the string for Spaces (Front & Back)
    //
    // First Cut off any spaces at the front
    //
    while ((indexString < COUNTOF(string)) &&
           (string[indexString] == szWideSpace[0]))
    {
        indexString++;
    }
    while ((indexString < COUNTOF(string)-1) && (string[indexString]))
    {
        trimmedString[indexTrimmedString++] = string[indexString++];
    }
    trimmedString[indexTrimmedString] = 0x00;

    //
    // Next Cut off any spaces at the end
    //
    end = (SHORT) wcslen(trimmedString)-1;
    while ((end >= 0) && (trimmedString[end] == szWideSpace[0]))
    {
        trimmedString[end--] = 0x00;
    }

    cbSize = (wcslen(string) + 1) * sizeof(*string);

    if (cbSize <= DWORD_MAX)
    {
        rc = XcvData(   pPort->hXcv,
                        L"PortIsValid",
                        (PBYTE) trimmedString,
                        (DWORD)cbSize,
                        (PBYTE) NULL,
                        0,
                        &cbNeeded,
                        &dwStatus);
    }
    else
    {
        rc = FALSE;
    }

    if (!rc) {
        return FALSE;

    } else if (dwStatus != ERROR_SUCCESS) {
        SetLastError(dwStatus);

        if ( (dwStatus == ERROR_INVALID_NAME) || (*trimmedString == 0x00) )
            Message( hwnd, MSG_ERROR, IDS_LOCALMONITOR, IDS_INVALIDPORTNAME_S, string );
        else
            ErrorMessage(hwnd, dwStatus);

        return FALSE;

    } else {
        pPort->pszPortName = AllocSplStr( trimmedString );
        pPort->dwRet = dwStatus;
        EndDialog( hwnd, ERROR_SUCCESS );
        return TRUE;
    }

}
Example #7
0
PINIPORT
CreatePortEntry(
    __in    LPTSTR  pszPortName
    )
/*++

Routine Description:
    Creates a IniPort entry for a port. Needs to be called inside monitor
    critical section.

Arguments:
    pszPortName       : Name of the port

Return Value:
      On success pointer to the IniPort stucture.
      On failure NULL

--*/
{
    PINIPORT    pIniPort    = NULL;
    HANDLE      DoneWriting = NULL;
    HANDLE      DoneReading = NULL;
    HANDLE      WakeUp      = NULL;
    LPWSTR      pszString   = NULL;

    SplInSem();


    DoneWriting = CreateEvent(NULL, FALSE, TRUE, NULL);
    if (!DoneWriting)
    {
        goto Fail;
    }

    WakeUp = CreateEvent(NULL, FALSE, FALSE, NULL);
    if (!WakeUp)
    {
        goto Fail;
    }
    //
    // manual-reset event, initially signal state
    //
    DoneReading = CreateEvent(NULL, TRUE, TRUE, NULL);
    if (!DoneReading)
    {
        goto Fail;
    }
    pIniPort = (PINIPORT) AllocSplMem(sizeof(*pIniPort));
    if (!pIniPort)
    {
        goto Fail;
    }
    pszString = AllocSplStr(pszPortName);
    if (!pszString)
    {
        goto Fail;
    }
    pIniPort->pNext         = NULL;
    pIniPort->signature     = PJ_SIGNATURE;
    pIniPort->DoneWriting   = DoneWriting;
    pIniPort->DoneReading   = DoneReading;
    pIniPort->WakeUp        = WakeUp;
    pIniPort->hUstatusThread= NULL;
    pIniPort->pszPortName   = pszString;

    pIniPort->pNext         = pIniFirstPort;
    pIniFirstPort           = pIniPort;
    return pIniPort;

Fail:
    if (DoneWriting)
    {
        CloseHandle (DoneWriting);
    }
    if (DoneReading)
    {
        CloseHandle (DoneReading);
    }
    if (WakeUp)
    {
        CloseHandle (WakeUp);
    }
    FreeSplMem (pszString);
    FreeSplMem (pIniPort);
    return NULL;
}
Example #8
0
DWORD WINAPI
CreateJob(PLOCAL_PRINTER_HANDLE pPrinterHandle)
{
    const WCHAR wszDoubleBackslash[] = L"\\";
    const DWORD cchDoubleBackslash = _countof(wszDoubleBackslash) - 1;

    DWORD cchMachineName;
    DWORD cchUserName;
    DWORD dwErrorCode;
    PLOCAL_JOB pJob;
    RPC_BINDING_HANDLE hServerBinding = NULL;
    RPC_WSTR pwszBinding = NULL;
    RPC_WSTR pwszMachineName = NULL;

    // Create a new job.
    pJob = DllAllocSplMem(sizeof(LOCAL_JOB));
    if (!pJob)
    {
        dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
        ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
        goto Cleanup;
    }

    // Reserve an ID for this job.
    if (!_GetNextJobID(&pJob->dwJobID))
    {
        dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
        goto Cleanup;
    }

    // Copy over defaults to the LOCAL_JOB structure.
    pJob->pPrinter = pPrinterHandle->pPrinter;
    pJob->pPrintProcessor = pPrinterHandle->pPrinter->pPrintProcessor;
    pJob->dwPriority = DEF_PRIORITY;
    pJob->dwStatus = JOB_STATUS_SPOOLING;
    pJob->pwszDatatype = AllocSplStr(pPrinterHandle->pwszDatatype);
    pJob->pwszDocumentName = AllocSplStr(wszDefaultDocumentName);
    pJob->pDevMode = DuplicateDevMode(pPrinterHandle->pDevMode);
    GetSystemTime(&pJob->stSubmitted);

    // Get the user name for the Job.
    cchUserName = UNLEN + 1;
    pJob->pwszUserName = DllAllocSplMem(cchUserName * sizeof(WCHAR));
    if (!GetUserNameW(pJob->pwszUserName, &cchUserName))
    {
        dwErrorCode = GetLastError();
        ERR("GetUserNameW failed with error %lu!\n", dwErrorCode);
        goto Cleanup;
    }

    // FIXME: For now, pwszNotifyName equals pwszUserName.
    pJob->pwszNotifyName = AllocSplStr(pJob->pwszUserName);

    // Get the name of the machine that submitted the Job over RPC.
    dwErrorCode = RpcBindingServerFromClient(NULL, &hServerBinding);
    if (dwErrorCode != RPC_S_OK)
    {
        ERR("RpcBindingServerFromClient failed with status %lu!\n", dwErrorCode);
        goto Cleanup;
    }

    dwErrorCode = RpcBindingToStringBindingW(hServerBinding, &pwszBinding);
    if (dwErrorCode != RPC_S_OK)
    {
        ERR("RpcBindingToStringBindingW failed with status %lu!\n", dwErrorCode);
        goto Cleanup;
    }

    dwErrorCode = RpcStringBindingParseW(pwszBinding, NULL, NULL, &pwszMachineName, NULL, NULL);
    if (dwErrorCode != RPC_S_OK)
    {
        ERR("RpcStringBindingParseW failed with status %lu!\n", dwErrorCode);
        goto Cleanup;
    }

    cchMachineName = wcslen(pwszMachineName);
    pJob->pwszMachineName = DllAllocSplMem((cchMachineName + cchDoubleBackslash + 1) * sizeof(WCHAR));
    CopyMemory(pJob->pwszMachineName, wszDoubleBackslash, cchDoubleBackslash * sizeof(WCHAR));
    CopyMemory(&pJob->pwszMachineName[cchDoubleBackslash], pwszMachineName, (cchMachineName + 1) * sizeof(WCHAR));

    // Add the job to the Global Job List.
    if (!InsertElementSkiplist(&GlobalJobList, pJob))
    {
        dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
        ERR("InsertElementSkiplist failed for job %lu for the GlobalJobList!\n", pJob->dwJobID);
        goto Cleanup;
    }

    // Add the job at the end of the Printer's Job List.
    // As all new jobs are created with default priority, we can be sure that it would always be inserted at the end.
    if (!InsertTailElementSkiplist(&pJob->pPrinter->JobList, pJob))
    {
        dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
        ERR("InsertTailElementSkiplist failed for job %lu for the Printer's Job List!\n", pJob->dwJobID);
        goto Cleanup;
    }

    // We were successful!
    pPrinterHandle->bStartedDoc = TRUE;
    pPrinterHandle->pJob = pJob;
    dwErrorCode = ERROR_SUCCESS;

    // Don't let the cleanup routine free this.
    pJob = NULL;

Cleanup:
    if (pJob)
        DllFreeSplMem(pJob);

    if (pwszMachineName)
        RpcStringFreeW(&pwszMachineName);

    if (pwszBinding)
        RpcStringFreeW(&pwszBinding);

    if (hServerBinding)
        RpcBindingFree(&hServerBinding);

    return dwErrorCode;
}
Example #9
0
PLOCAL_JOB
ReadJobShadowFile(PCWSTR pwszFilePath)
{
    DWORD cbFileSize;
    DWORD cbRead;
    HANDLE hFile = INVALID_HANDLE_VALUE;
    PLOCAL_JOB pJob;
    PLOCAL_JOB pReturnValue = NULL;
    PLOCAL_PRINTER pPrinter;
    PLOCAL_PRINT_PROCESSOR pPrintProcessor;
    PSHD_HEADER pShadowFile = NULL;
    PWSTR pwszPrinterName;
    PWSTR pwszPrintProcessor;

    // Try to open the file.
    hFile = CreateFileW(pwszFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
    if (hFile == INVALID_HANDLE_VALUE)
    {
        ERR("CreateFileW failed with error %lu for file \"%S\"!\n", GetLastError(), pwszFilePath);
        goto Cleanup;
    }

    // Get its file size (small enough for a single DWORD) and allocate memory for all of it.
    cbFileSize = GetFileSize(hFile, NULL);
    pShadowFile = DllAllocSplMem(cbFileSize);
    if (!pShadowFile)
    {
        ERR("DllAllocSplMem failed with error %lu for file \"%S\"!\n", GetLastError(), pwszFilePath);
        goto Cleanup;
    }

    // Read the entire file.
    if (!ReadFile(hFile, pShadowFile, cbFileSize, &cbRead, NULL))
    {
        ERR("ReadFile failed with error %lu for file \"%S\"!\n", GetLastError(), pwszFilePath);
        goto Cleanup;
    }

    // Check signature and header size.
    if (pShadowFile->dwSignature != SHD_WIN2003_SIGNATURE || pShadowFile->cbHeader != sizeof(SHD_HEADER))
    {
        ERR("Signature or Header Size mismatch for file \"%S\"!\n", pwszFilePath);
        goto Cleanup;
    }

    // Retrieve the associated printer from the list.
    pwszPrinterName = (PWSTR)((ULONG_PTR)pShadowFile + pShadowFile->offPrinterName);
    pPrinter = LookupElementSkiplist(&PrinterList, &pwszPrinterName, NULL);
    if (!pPrinter)
    {
        ERR("Shadow file \"%S\" references a non-existing printer \"%S\"!\n", pwszFilePath, pwszPrinterName);
        goto Cleanup;
    }

    // Retrieve the associated Print Processor from the list.
    pwszPrintProcessor = (PWSTR)((ULONG_PTR)pShadowFile + pShadowFile->offPrintProcessor);
    pPrintProcessor = FindPrintProcessor(pwszPrintProcessor);
    if (!pPrintProcessor)
    {
        ERR("Shadow file \"%S\" references a non-existing Print Processor \"%S\"!\n", pwszFilePath, pwszPrintProcessor);
        goto Cleanup;
    }

    // Create a new job structure and copy over the relevant fields.
    pJob = DllAllocSplMem(sizeof(LOCAL_JOB));
    if (!pJob)
    {
        ERR("DllAllocSplMem failed with error %lu for file \"%S\"!\n", GetLastError(), pwszFilePath);
        goto Cleanup;
    }

    pJob->dwJobID = pShadowFile->dwJobID;
    pJob->dwPriority = pShadowFile->dwPriority;
    pJob->dwStartTime = pShadowFile->dwStartTime;
    pJob->dwTotalPages = pShadowFile->dwTotalPages;
    pJob->dwUntilTime = pShadowFile->dwUntilTime;
    pJob->pPrinter = pPrinter;
    pJob->pPrintProcessor = pPrintProcessor;
    pJob->pDevMode = DuplicateDevMode((PDEVMODEW)((ULONG_PTR)pShadowFile + pShadowFile->offDevMode));
    pJob->pwszDatatype = AllocSplStr((PCWSTR)((ULONG_PTR)pShadowFile + pShadowFile->offDatatype));
    pJob->pwszMachineName = AllocSplStr((PCWSTR)((ULONG_PTR)pShadowFile + pShadowFile->offMachineName));
    CopyMemory(&pJob->stSubmitted, &pShadowFile->stSubmitted, sizeof(SYSTEMTIME));

    // Copy the optional values.
    if (pShadowFile->offDocumentName)
        pJob->pwszDocumentName = AllocSplStr((PCWSTR)((ULONG_PTR)pShadowFile + pShadowFile->offDocumentName));

    if (pShadowFile->offNotifyName)
        pJob->pwszNotifyName = AllocSplStr((PCWSTR)((ULONG_PTR)pShadowFile + pShadowFile->offNotifyName));

    if (pShadowFile->offPrintProcessorParameters)
        pJob->pwszPrintProcessorParameters = AllocSplStr((PCWSTR)((ULONG_PTR)pShadowFile + pShadowFile->offPrintProcessorParameters));

    if (pShadowFile->offUserName)
        pJob->pwszUserName = AllocSplStr((PCWSTR)((ULONG_PTR)pShadowFile + pShadowFile->offUserName));

    // Jobs read from shadow files were always added using AddJob.
    pJob->bAddedJob = TRUE;

    pReturnValue = pJob;

Cleanup:
    if (pShadowFile)
        DllFreeSplMem(pShadowFile);

    if (hFile != INVALID_HANDLE_VALUE)
        CloseHandle(hFile);

    return pReturnValue;
}
Example #10
0
/*++
*******************************************************************
    O p e n P r i n t P r o c e s s o r

    Routine Description:

    Arguments:
        pPrinterName            => name of printer we are
                                    opening for
        pPrintProcessorOpenData => information used for opening
                                    the print processor

    Return Value:
        PPRINTPROCESSORDATA => processor data of opened
                                processor if successful
        NULL if failed - caller uses GetLastError for reason

    NOTE: OpenPrinter will be called iff this returns a valid handle
          (and we're not journal)

*******************************************************************
--*/
HANDLE
OpenPrintProcessor(
    _In_ LPWSTR                  pPrinterName,
    _In_ PPRINTPROCESSOROPENDATA pPrintProcessorOpenData
)
{
    PPRINTPROCESSORDATA pData;
    LPWSTR              *pMyDatatypes    = Datatypes;
    DWORD               uDatatype        = 0;
    HANDLE              hPrinter         = 0;
    HDC                 hDC              = 0;
    PDEVMODEW           pDevmode         = NULL;
    DWORD               dwNewDevmodeSize = 0;


    /** If the caller passed a NULL for the open data, fail the call.
        pPrintProcessorOpenData->pDevMode can be NULL **/

    if (!pPrintProcessorOpenData ||
        !pPrintProcessorOpenData->pDatatype ||
        !*pPrintProcessorOpenData->pDatatype) {

        SetLastError(ERROR_INVALID_PARAMETER);
        return NULL;
    }

    /** Search for the data type index we are opening for **/

    while (*pMyDatatypes) {

        if (!_wcsicmp(*pMyDatatypes,pPrintProcessorOpenData->pDatatype)) {
            break;
        }
        pMyDatatypes++;
        uDatatype++;
    }

    /** Allocate a buffer for the print processor data to return **/

    pData = (PPRINTPROCESSORDATA)AllocSplMem(sizeof(PRINTPROCESSORDATA));

    if (!pData) {
        ODS(("Alloc failed in OpenPrintProcessor, while printing on %ws\n", pPrinterName));
        return NULL;
    }

    ZeroMemory ( pData, sizeof (PRINTPROCESSORDATA) );

    /** Open the processor accordingly **/

    switch (uDatatype) {

    case PRINTPROCESSOR_TYPE_RAW:
        if (!OpenPrinter(pPrinterName, &hPrinter, NULL))
            goto Fail;
        break;

    case PRINTPROCESSOR_TYPE_EMF_50_1:
    case PRINTPROCESSOR_TYPE_EMF_50_2:
    case PRINTPROCESSOR_TYPE_EMF_50_3:

        if(pPrintProcessorOpenData->pDevMode)
        {
            if ( ! SUCCEEDED ( DWordAdd(pPrintProcessorOpenData->pDevMode->dmSize,
                                        pPrintProcessorOpenData->pDevMode->dmDriverExtra,
                                        &dwNewDevmodeSize) )
                 ||

                 (NULL == (pDevmode=(PDEVMODE)AllocSplMem( dwNewDevmodeSize ) ) )
               )
            {
                goto Fail;
            }
            memcpy(pDevmode,
                   pPrintProcessorOpenData->pDevMode,
                   pPrintProcessorOpenData->pDevMode->dmSize+
                   pPrintProcessorOpenData->pDevMode->dmDriverExtra);
        }
        break;

    case PRINTPROCESSOR_TYPE_TEXT:
        if ((hDC = CreateDC(
                 L"", pPrinterName, L"",
                 pPrintProcessorOpenData->pDevMode))
            == NULL)
            goto Fail;
        break;

    default:
        SetLastError(ERROR_INVALID_DATATYPE);
        goto Fail;
    }

    /** Fill in the print processors information **/

    pData->cb          = sizeof(PRINTPROCESSORDATA);
    pData->signature   = PRINTPROCESSORDATA_SIGNATURE;
    pData->JobId       = pPrintProcessorOpenData->JobId;
    pData->hPrinter    = hPrinter;
    pData->semPaused   = CreateEvent(NULL, TRUE, TRUE,NULL);
    pData->uDatatype   = uDatatype;
    pData->hDC         = hDC;
    pData->Copies      = 1;
    pData->TabSize     = BASE_TAB_SIZE;

    /** Allocate and fill in the processors strings **/

    pData->pPrinterName = AllocSplStr(pPrinterName);
    pData->pDatatype    = AllocSplStr(pPrintProcessorOpenData->pDatatype);
    pData->pDocument    = AllocSplStr(pPrintProcessorOpenData->pDocumentName);
    pData->pOutputFile  = AllocSplStr(pPrintProcessorOpenData->pOutputFile);
    pData->pParameters  = AllocSplStr(pPrintProcessorOpenData->pParameters);
    pData->pDevmode     = pDevmode;
    pData->pPrinterNameFromOpenData = AllocSplStr(pPrintProcessorOpenData->pPrinterName);

    //
    // Check for validity of pData. In the AllocSplStr above, if RHS is non-null, then LHS
    // should be non-null.
    //
    if ( NULL == pData->semPaused ||
        ( NULL != pPrinterName                           && NULL == pData->pPrinterName )  ||
        ( NULL != pPrintProcessorOpenData->pDatatype     && NULL == pData->pDatatype    )  ||
        ( NULL != pPrintProcessorOpenData->pDocumentName && NULL == pData->pDocument    )  ||
        ( NULL != pPrintProcessorOpenData->pOutputFile   && NULL == pData->pOutputFile  )  ||
        ( NULL != pPrintProcessorOpenData->pParameters   && NULL == pData->pParameters  )  ||
        ( NULL != pPrintProcessorOpenData->pPrinterName  && NULL == pData->pPrinterNameFromOpenData)
      )
    {
        goto Fail;
    }


    /** Parse the parameters string **/
    if (pData->pParameters) {
        ULONG   value;
        USHORT  length = sizeof(ULONG);

        /**
            Look to see if there is a COPIES=n key/value in the
            Parameters field of this job.  This tells us the number
            of times to play the data.
        **/

        if (pData->pParameters) {

            GetKeyValue(pData->pParameters,
                        pCopiesKey,
                        VALUE_ULONG,
                        &length,
                        &value);

            if (length == sizeof(ULONG)) {
                pData->Copies = value;
            }
        }

        /** If this is a text job, see if the tab size is in there **/

        if (uDatatype == PRINTPROCESSOR_TYPE_TEXT) {
            length = sizeof(ULONG);

            GetKeyValue(pData->pParameters,
                        pTabsKey,
                        VALUE_ULONG,
                        &length,
                        &value);

            if ((length == sizeof(ULONG)) && value) {
                pData->TabSize = value;
            }
        }
    } /* If we have a parameter string */

    /**
        If we are doing copies, we need to check to see if
        this is a direct or spooled job.  If it is direct, then
        we can't do copies because we can't rewind the data stream.
    **/

    if (pData->Copies > 1) {
        ULONG           Error;
        PPRINTER_INFO_2 pPrinterInfo2;

        /** If we don't already have the printer open, open it **/

        if (uDatatype != PRINTPROCESSOR_TYPE_RAW
            ) {

            OpenPrinter(pPrinterName, &hPrinter, NULL);
        }
        if (hPrinter && hPrinter != INVALID_HANDLE_VALUE) {

            /** Get the printer info - this returns an allocated buffer **/

            pPrinterInfo2 = (PPRINTER_INFO_2)GetPrinterInfo(hPrinter, 2, &Error);

            /** If we couldn't get the info, be safe and don't do copies **/

            if (!pPrinterInfo2) {
                ODS(("GetPrinter failed - falling back to 1 copy\n"));
                pData->Copies = 1;
            }
            else {
                if (pPrinterInfo2->Attributes & PRINTER_ATTRIBUTE_DIRECT) {
                    pData->Copies = 1;
                }
                FreeSplMem((PUCHAR)pPrinterInfo2);
            }

            /** If we just opened the printer, close it **/

            if (uDatatype != PRINTPROCESSOR_TYPE_RAW
                ) {

                ClosePrinter(hPrinter);
            }
        }
        else {
            pData->Copies = 1;
        }
    }

    return (HANDLE)pData;

Fail:
    BReleasePPData(&pData);

    return FALSE;
}
Example #11
0
HANDLE
CreatePrinterHandle(
    LPWSTR      pPrinterName,
    PINIPRINTER pIniPrinter,
    PINIPORT    pIniPort,
    PINIPORT    pIniNetPort,
    PINIJOB     pIniJob,
    DWORD       TypeofHandle,
    HANDLE      hPort,
    PPRINTER_DEFAULTS pDefaults,
    PINISPOOLER pIniSpooler,
    DWORD       AccessRequested,
    LPBYTE      pSplClientInfo,
    DWORD   dwLevel,
    HANDLE  hReadFile
    )
{
    PSPOOL              pSpool = NULL;
    BOOL                bStatus = FALSE;
    HANDLE              hReturnHandle = NULL;
    LPDEVMODE           pDevMode = NULL;
    PSPLCLIENT_INFO_1   pSplClientInfo1 = (PSPLCLIENT_INFO_1)pSplClientInfo;

    SPLASSERT( pIniSpooler->signature == ISP_SIGNATURE );

    if ( dwLevel && ( dwLevel != 1 || !pSplClientInfo) ) {

        DBGMSG(DBG_ERROR,
               ("CreatePrintHandle: Invalid client info %x - %d\n",
                pSplClientInfo, dwLevel));
        pSplClientInfo = NULL;
    }

 try {

    pSpool = (PSPOOL)AllocSplMem( SPOOL_SIZE );

    if ( pSpool == NULL ) {
        DBGMSG( DBG_WARNING, ("CreatePrinterHandle failed to allocate SPOOL %d\n", GetLastError() ));
        leave;
    }

    pSpool->signature = SJ_SIGNATURE;
    pSpool->pIniPrinter = pIniPrinter;
    pSpool->hReadFile = hReadFile;

    //
    // We get other useful info like build #, client architecture
    // we do not need this info now -- so we do not put it in PSPOOL
    //
    if ( (TypeofHandle & PRINTER_HANDLE_REMOTE) ) {

        if ( !pSplClientInfo ) {

            TypeofHandle |= PRINTER_HANDLE_3XCLIENT;
        } else if ( dwLevel == 1 ) {
            SPLASSERT(pSplClientInfo1->pUserName && pSplClientInfo1->pMachineName);
            pSpool->pUserName = AllocSplStr(pSplClientInfo1->pUserName);
            pSpool->pMachineName = AllocSplStr(pSplClientInfo1->pMachineName);
            if ( !pSpool->pUserName || !pSpool->pMachineName ) {

                DBGMSG(DBG_WARNING, ("CreatePrinterHandle: could not allocate memory for user name or machine name\n"));
            }
        }
    }

    if ( TypeofHandle & PRINTER_HANDLE_SERVER ) {

        bStatus = ValidateObjectAccess( SPOOLER_OBJECT_SERVER,
                                        AccessRequested,
                                        pSpool, pIniSpooler );
    } else {

        bStatus = ValidateObjectAccess( SPOOLER_OBJECT_PRINTER,
                                        AccessRequested,
                                        pSpool, pIniSpooler );
    }

    if ( !bStatus ) {

        SetLastError(ERROR_ACCESS_DENIED);
        leave;
    }

    MapGenericToSpecificAccess(SPOOLER_OBJECT_PRINTER,
                                   pSpool->GrantedAccess,
                                   &pSpool->GrantedAccess);


    pSpool->pIniPort     = pIniPort;
    pSpool->pIniNetPort  = pIniNetPort;
    pSpool->pIniJob      = pIniJob;
    pSpool->TypeofHandle = TypeofHandle;
    pSpool->hPort        = hPort;
    pSpool->Status       = 0;
    pSpool->pDevMode     = NULL;
    pSpool->pName        = AllocSplStr( pPrinterName );

    if ( pSpool->pName == NULL ) {
        leave;
    }

    pSpool->pIniSpooler = pIniSpooler;

    if ( pIniPrinter ) {

        if ( pDefaults ) {

            //
            // Allocate DevMode
            //


            if ( pDefaults->pDevMode ) {

                pDevMode = pDefaults->pDevMode;

            } else {

                pDevMode = pIniPrinter->pDevMode;
            }

            if ( pDevMode != NULL  ) {

                pSpool->pDevMode = AllocSplMem( pDevMode->dmSize + pDevMode->dmDriverExtra );

                if ( pSpool->pDevMode == NULL ) {

                    DBGMSG(DBG_WARNING, ("CreatePrinterHandle failed allocation for devmode %d\n", GetLastError() ));
                    leave;
                }
                memcpy( pSpool->pDevMode, pDevMode, pDevMode->dmSize + pDevMode->dmDriverExtra );
            }
        }

        //
        //  Allocate Datype and Print Processor
        //

        if ( pDefaults && pDefaults->pDatatype ) {

                pSpool->pDatatype = AllocSplStr( pDefaults->pDatatype );
                pSpool->pIniPrintProc = FindDatatype( pIniPrinter->pIniPrintProc, pSpool->pDatatype );

        } else {

            pSpool->pDatatype = AllocSplStr( pIniPrinter->pDatatype );
            pSpool->pIniPrintProc = pIniPrinter->pIniPrintProc;
        }


        if ( pSpool->pIniPrintProc == NULL ) {
            DBGMSG( DBG_WARNING,("CreatePrinterHandle failed to PrintProcessor for datatype %ws %d\n",
                    pSpool->pDatatype, GetLastError() ));
            leave;
        }

        SPLASSERT( pSpool->pIniPrintProc->signature == IPP_SIGNATURE );

        pSpool->pIniPrintProc->cRef++;

        if ( pSpool->pDatatype == NULL ) {
            DBGMSG( DBG_WARNING,("CreatePrinterHandle failed to allocate DataType %x\n", GetLastError() ));
            leave;
        }

    }

    // Add us to the linked list of handles for this printer.
    // This will be scanned when a change occurs on the printer,
    // and will be updated with a flag indicating what type of
    // change it was.
    // There is a flag for each handle, because we cannot guarantee
    // that all threads will have time to reference a flag in the
    // INIPRINTER before it is updated.

    if ( TypeofHandle & PRINTER_HANDLE_PRINTER ) {

        pSpool->pNext = pSpool->pIniPrinter->pSpool;
        pSpool->pIniPrinter->pSpool = pSpool;

    } else if ( TypeofHandle & PRINTER_HANDLE_SERVER ) {

        //
        // For server handles, hang them off the global IniSpooler:
        //

        pSpool->pNext = pIniSpooler->pSpool;
        pIniSpooler->pSpool = pSpool;

        INCSPOOLERREF( pIniSpooler );

    }

    //  Note Only PRINTER_HANDLE_PRINTER are attatched to the
    //  pIniPrinter, since those are the handle which will require
    //  change notifications.

    if ( pSpool->pIniPrinter != NULL ) {

        INCPRINTERREF( pSpool->pIniPrinter );
    }

    hReturnHandle = (HANDLE)pSpool;

 } finally {

    if ( hReturnHandle == NULL ) {

        // Failure CleanUP

        if ( pSpool != NULL ) {

            FreeSplStr(pSpool->pUserName);
            FreeSplStr(pSpool->pMachineName);
            FreeSplStr( pSpool->pName ) ;
            FreeSplStr( pSpool->pDatatype );

            if ( pSpool->pIniPrintProc != NULL )
                pSpool->pIniPrintProc->cRef--;

            if ( pSpool->pDevMode )
                FreeSplMem( pSpool->pDevMode );

            FreeSplMem( pSpool );
            pSpool = NULL;

        }
    }
}
    return hReturnHandle;
}