示例#1
0
//=============================================================================
CSaveData::CSaveData()
:   m_pDataBuffer(NULL),
    m_FileHandle(NULL),
    m_ulFrameCount(DEFAULT_FRAME_COUNT),
    m_ulBufferSize(DEFAULT_BUFFER_SIZE),
    m_ulFrameSize(DEFAULT_FRAME_SIZE),
    m_ulBufferPtr(0),
    m_ulFramePtr(0),
    m_fFrameUsed(NULL),
    m_pFilePtr(NULL),
    m_fWriteDisabled(FALSE),
    m_bInitialized(FALSE)
{

    PAGED_CODE();

    m_waveFormat = NULL;
    m_FileHeader.dwRiff           = RIFF_TAG;
    m_FileHeader.dwFileSize       = 0;
    m_FileHeader.dwWave           = WAVE_TAG;
    m_FileHeader.dwFormat         = FMT__TAG;
    m_FileHeader.dwFormatLength   = sizeof(WAVEFORMATEX);

    m_DataHeader.dwData           = DATA_TAG;
    m_DataHeader.dwDataLength     = 0;

    RtlZeroMemory(&m_objectAttributes, sizeof(m_objectAttributes));

    m_ulStreamId++;
    InitializeWorkItems(GetDeviceObject());
} // CSaveData
示例#2
0
VOID HandleMediaChangeEvent( UINT uidCdRom )
{
    /*
     * Local variables
     */
    HANDLE                  hDevice;
    ULONG                   id;
    DWORD                   cb;
    DWORD                   dwLogicalDrives;
    DWORD                   dwDriveMask;
    DWORD                   dwDriveCount;
    DWORD                   dwRecipients;
    BOOL                    bResult;
    INT                     nCurrentTry;
    NTSTATUS                Status;
    UNICODE_STRING          ustrCdRom;
    UNICODE_STRING          ustrCdRomId;
    UNICODE_STRING          ustrAnyCdRom;
    UNICODE_STRING          ustrNtPath;
    DEV_BROADCAST_VOLUME    dbcvInfo;
    LPWSTR                  lpszCdRom = TEXT("\\Device\\CdRom");
    WCHAR                   szDrive[] = TEXT("A:\\");
    WCHAR                   szDevice[] = TEXT("\\\\.\\A:");
    WCHAR                   wcDrive;
    WCHAR                   szCdRom[32];
    WCHAR                   szBuff[256];


    UserAssert(uidCdRom >= 0 && uidCdRom < NUM_MEDIA_EVENTS);  // at most 24 cd-rom drives in system


    /*
     * Some initializations
     */
    RtlInitUnicodeString( &ustrAnyCdRom, lpszCdRom );
    wcDrive = UNICODE_NULL;

    /*
     * Form the \Device\CdRomX name based on uidCdRom
     */
    wsprintfW( szCdRom, L"\\Device\\CdRom%d", uidCdRom );
    RtlInitUnicodeString( &ustrCdRom, szCdRom );

    /*
     * The uidCdRom parameter tells us which CD-ROM device generated the
     * MediaChange event.  We need to map this device back to it's logical
     * drive letter because WM_DEVICECHANGE is based on drive letters.
     *
     * To avoid always searching all logical drives, we cache the last
     * associated drive letter.  We still need to check this every time
     * we get notified because WinDisk can remap drive letters.
     */
    if (wcDriveCache[uidCdRom]) {
        /*
         * Convert our DOS path name to a NT path name
         */
        ustrNtPath.MaximumLength = sizeof(szBuff);
        ustrNtPath.Length = 0;
        ustrNtPath.Buffer = szBuff;
        bResult = GetDeviceObject(wcDriveCache[uidCdRom], &ustrNtPath);
        if (bResult) {
            /*
             * Check to see if this drive letter is the one that maps
             * to the CD-ROM drive that just notified us.
             */
            if (RtlEqualUnicodeString(&ustrCdRom, &ustrNtPath, TRUE)) {
                /*
                 * Yes, we found a match
                 */
                wcDrive  = wcDriveCache[uidCdRom];
            }
        }
    }

    if (!wcDrive) {
        /*
         * Either the cache wasn't initialized, or we had a re-mapping
         * of drive letters.  Scan all drive letters looking for CD-ROM
         * devices and update the cache as we go.
         */
        RtlZeroMemory(wcDriveCache, sizeof(wcDriveCache));
        szDrive[0] = L'A';
        szDevice[4] = L'A';
        dwDriveCount = 26; //Max number of drive letters
        dwDriveMask = 1; //Max number of drive letters
        dwLogicalDrives = GetLogicalDrives();

        while (dwDriveCount) {
            /*
             * Is this logical drive a CD-ROM?
             */

//
// JOHNC - Remove after GetDriveType() is fixed
            if ((dwLogicalDrives & dwDriveMask) &&
                GetDriveType(szDrive) == DRIVE_CDROM) {
                /*
                 * For this CD-ROM drive, find it's NT path.
                 */
                ustrNtPath.MaximumLength = sizeof(szBuff);
                ustrNtPath.Length = 0;
                ustrNtPath.Buffer = szBuff;
                bResult = GetDeviceObject(szDrive[0], &ustrNtPath);
                if (bResult) {
                    /*
                     * Make sure the string is in the form \Device\CdRom
                     */
                    if (RtlPrefixUnicodeString(&ustrAnyCdRom, &ustrNtPath, TRUE)) {
                        /*
                         * Now find it's id.  We have a string that looks like
                         * \Device\CdRom??? where ??? is the unit id
                         */
                        RtlInitUnicodeString(&ustrCdRomId,
                                             (PWSTR)((PSTR)(ustrNtPath.Buffer)+ustrAnyCdRom.Length));
                        RtlUnicodeStringToInteger(&ustrCdRomId, 10, &id);
                        UserAssert(id >= 0 && id < NUM_MEDIA_EVENTS);
                        wcDriveCache[id] = szDrive[0];

                            //Initially set State to Unknown
                        aDriveState[id] = DS_UNKNOWN;

                        /*
                         * If this is the device that notified us, remember its
                         * drive letter so we can broadcase WM_DEVICECHANGE
                         */
                        if (uidCdRom == id) {
                            wcDrive  = szDrive[0];
                        }
                    }
                }
            }

            /*
             * Try the next drive
             */
            szDrive[0] = szDrive[0] + 1;
            szDevice[4] = szDevice[4] + 1;
            dwDriveMask <<= 1;
            --dwDriveCount;
        }
    }

    /*
     * If we found a logical drive, determine the media state for the drive
     * and broadcast the WM_DEVICECHANGE notification.
     */
    if (wcDrive) {
        /*
         * Get the Media status of this drive.  Assume media is not
         * present in the case of an error.
         */
        szDevice[4] = wcDrive;

        hDevice = CreateFile(szDevice,
                             GENERIC_READ,
                             FILE_SHARE_READ,
                             NULL,
                             OPEN_EXISTING,
                             FILE_ATTRIBUTE_NORMAL,
                             NULL);
        if (hDevice == INVALID_HANDLE_VALUE) {
#ifdef DEBUG
        KdPrint(("        CreateFile( '%ls' ) Failed. Error %lx\n",
                szDevice,GetLastError()));
#endif
            return;
        }

        /*
         * Loop and check the CD-ROM to see if media is available.  We need
         * this loop because some CD-ROM drives notify us that media has
         * arrived before the drive has recognized that it had new media.
         */
        for (nCurrentTry = 0; nCurrentTry < MAX_TRIES; nCurrentTry++) {

            /*
             * See if media is present
             */
            bResult = (DWORD)DeviceIoControl(hDevice,
                                             IOCTL_DISK_CHECK_VERIFY,
                                             NULL,
                                             0,
                                             NULL,
                                             0,
                                             &cb,
                                             NULL);

            if (bResult) {
                /*
                 * Media is present, change the state to Inserted.
                 */
                aDriveState[uidCdRom] = DS_INSERTED;
                break;
            }

            /*
             * Media wasn't present, so we need to look at GetLastError() to see
             * if DeviceIoControl() failed.  If so we may want to try again.
             */
            if (GetLastError() == ERROR_NOT_READY) {
                Sleep(500); // 1/2 second

                /*
                * We only want to retry if we the prev State was UNKNOWN or
                * EJECTED. If the previous State was INSERTED it means that
                * this event is the removal event
                */
                if(aDriveState[uidCdRom]== DS_UNKNOWN ||
                        aDriveState[uidCdRom] == DS_EJECTED) {
                    continue;

                }
            }

            /*
             * Call failed.  Assume worst case and say the media has been removed.
             */
            aDriveState[uidCdRom] = DS_EJECTED;
            break;
        }

        /*
         * Close the handle to the CD-ROM device
         */
        CloseHandle(hDevice);

        /*
         * Initialize the structures used for BroadcastSystemMessage
         */
        dbcvInfo.dbcv_size = sizeof(dbcvInfo);
        dbcvInfo.dbcv_devicetype = DBT_DEVTYP_VOLUME;
        dbcvInfo.dbcv_reserved = 0;
        dbcvInfo.dbcv_flags = DBTF_MEDIA;
        dbcvInfo.dbcv_unitmask = (1 << (wcDrive - L'A'));

        dwRecipients = BSM_ALLCOMPONENTS | BSM_ALLDESKTOPS;

        /*
         * Temporarily we must assign this thread to a desktop so we can
         * call USER's BroascastSystemMessage() routine.  We call the
         * private SetThreadDesktopToDefault() to assign ourselves to the
         * desktop that is currently receiving input.
         */
        Status = NtUserSetInformationThread(NtCurrentThread(),
                                            UserThreadUseActiveDesktop,
                                            NULL, 0);
        if (NT_SUCCESS(Status)) {
            /*
             * Broadcast the message
             */
            BroadcastSystemMessage(BSF_FORCEIFHUNG,
                                   &dwRecipients,
                                   WM_DEVICECHANGE,
// HACK: need to or 0x8000 in wParam
//       because this is a flag to let
//       BSM know that lParam is a pointer
//       to a data structure.
                                   0x8000 | ((bResult) ? DBT_DEVICEARRIVAL : DBT_DEVICEREMOVECOMPLETE),
                                   (LPARAM)&dbcvInfo);

#ifdef DEBUG
        KdPrint(("        Message Broadcast for '%lc:'\n", wcDrive));
#endif
            /*
             * Set our thread's desktop back to NULL.  This will decrement
             * the desktop's reference count.
             */
            hDevice = NULL;
            NtUserSetInformationThread(NtCurrentThread(),
                                       UserThreadUseDesktop,
                                       &hDevice, // hDevice = NULL
                                       sizeof(HANDLE));
        }
    }
}