Esempio n. 1
0
HRESULT CBasePlayer::GetGdiplusEncoderClsid(__in LPCWSTR pwszFormat, __out GUID *pGUID)
{
	HRESULT hr = E_FAIL;
	UINT  nEncoders = 0;          // number of image encoders
	UINT  nSize = 0;              // size of the image encoder array in bytes
	CAutoVectorPtr<BYTE> spData;
	Gdiplus::ImageCodecInfo* pImageCodecInfo = NULL;
	Gdiplus::Status status;
	bool fFound = false;

	// param check

	if ((pwszFormat == NULL) || (pwszFormat[0] == 0) || (pGUID == NULL))
	{
		return E_POINTER;
	}

	*pGUID = GUID_NULL;
	status = Gdiplus::GetImageEncodersSize(&nEncoders, &nSize);

	if ((status != Gdiplus::Ok) || (nSize == 0))
	{
		return E_FAIL;
	}

	spData.Allocate(nSize);

	if (spData == NULL)
	{
		return E_FAIL;
	}

	pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(BYTE*)spData;

	status = Gdiplus::GetImageEncoders(nEncoders, nSize, pImageCodecInfo);

	if (status != Gdiplus::Ok)
	{
		return E_FAIL;
	}

	for (UINT j = 0; j < nEncoders; ++j)
	{
		if (wcscmp(pImageCodecInfo[j].MimeType, pwszFormat) == 0)
		{
			*pGUID = pImageCodecInfo[j].Clsid;
			fFound = true;
			break;
		}
	}

	hr = fFound ? S_OK : E_FAIL;

	return hr;
}
Esempio n. 2
0
HRESULT CUTF8::Parse(CMatroskaNode* pMN)
{
    Empty();
    CAutoVectorPtr<BYTE> buff;
    if (!buff.Allocate((UINT)pMN->m_len + 1) || S_OK != pMN->Read(buff, pMN->m_len)) {
        return E_FAIL;
    }
    buff[pMN->m_len] = 0;
    CStringW::operator = (UTF8To16((LPCSTR)(BYTE*)buff));
    return S_OK;
}
Esempio n. 3
0
BOOL CAuthDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	CWinApp* pApp = AfxGetApp();

	if (pApp->m_pszRegistryKey) {
		CRegKey hSecKey(pApp->GetSectionKey(IDS_R_LOGINS));

		if (hSecKey) {
			int i = 0;
			TCHAR username[256], password[256];

			for (;;) {
				DWORD unlen = _countof(username);
				DWORD pwlen = sizeof(password);
				DWORD type = REG_SZ;

				if (ERROR_SUCCESS == RegEnumValue(hSecKey, i++, username, &unlen, 0, &type, (BYTE*)password, &pwlen)) {
					m_logins[username] = DEncrypt(password);
					m_usernamectrl.AddString(username);
				} else {
					break;
				}
			}
		}
	} else {
		CAutoVectorPtr<TCHAR> buff;
		buff.Allocate(32767/sizeof(TCHAR));

		DWORD len = GetPrivateProfileSection(IDS_R_LOGINS, buff, 32767/sizeof(TCHAR), pApp->m_pszProfileName);

		TCHAR* p = buff;
		while (*p && len > 0) {
			CString str = p;
			p += str.GetLength()+1;
			len -= str.GetLength()+1;
			CAtlList<CString> sl;
			Explode(str, sl, '=', 2);

			if (sl.GetCount() == 2) {
				m_logins[sl.GetHead()] = DEncrypt(sl.GetTail());
				m_usernamectrl.AddString(sl.GetHead());
			}
		}
	}

	m_usernamectrl.SetFocus();

	return TRUE;
}
Esempio n. 4
0
LRESULT CALLBACK COpenFileDlg::WindowProcNew(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    if(message ==  WM_COMMAND && HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDOK
            && m_fAllowDirSelection)
    {
        CAutoVectorPtr<TCHAR> path;
        path.Allocate(MAX_PATH+1); // MAX_PATH should be bigger for multiple selection, but we are only interested if it's zero length
        // note: allocating MAX_PATH only will cause a buffer overrun for too long strings, and will result in a silent app disappearing crash, 100% reproducable
        if(::GetDlgItemText(hwnd, cmb13, (TCHAR*)path, MAX_PATH) == 0)
            ::SendMessage(hwnd, CDM_SETCONTROLTEXT, edt1, (LPARAM)__DUMMY__);
    }

    return CallWindowProc(COpenFileDlg::m_wndProc, hwnd, message, wParam, lParam);
}
Esempio n. 5
0
LRESULT CALLBACK COpenFileDlg::WindowProcNew(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	if (message ==  WM_COMMAND && HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDOK
			&& m_fAllowDirSelection) {
		CAutoVectorPtr<TCHAR> path;
		path.Allocate(_MAX_PATH+1);

		if (::GetDlgItemText(hwnd, cmb13, (TCHAR*)path, _MAX_PATH) == 0) {
			::SendMessage(hwnd, CDM_SETCONTROLTEXT, edt1, (LPARAM)__DUMMY__);
		}
	}

	return CallWindowProc(COpenFileDlg::m_wndProc, hwnd, message, wParam, lParam);
}
Esempio n. 6
0
bool CDVDSession::SendKey(DVD_KEY_TYPE KeyType, BYTE* pKeyData)
{
    CAutoVectorPtr<BYTE> key;
    DVD_COPY_PROTECT_KEY* pKey = nullptr;

    auto allocateKey = [&](ULONG len) {
        bool bSuccess = key.Allocate(len);
        if (bSuccess) {
            pKey = (DVD_COPY_PROTECT_KEY*)(BYTE*)key;
            pKey->KeyLength = len;
        }
        return bSuccess;
    };

    switch (KeyType) {
        case DvdChallengeKey:
            if (allocateKey(DVD_CHALLENGE_KEY_LENGTH)) {
                Reverse(pKey->KeyData, pKeyData, 10);
            }
            break;
        case DvdBusKey2:
            if (allocateKey(DVD_BUS_KEY_LENGTH)) {
                Reverse(pKey->KeyData, pKeyData, 5);
            }
            break;
        default:
            break;
    }

    if (!pKey) {
        return false;
    }

    pKey->SessionId = m_session;
    pKey->KeyType = KeyType;
    pKey->KeyFlags = 0;

    DWORD dwBytesReturned;
    return !!DeviceIoControl(m_hDrive, IOCTL_DVD_SEND_KEY, pKey, pKey->KeyLength, nullptr, 0, &dwBytesReturned, nullptr);
}
Esempio n. 7
0
// Save icon referenced by handle 'hIcon' as file with name 'szPath'.
// The generated ICO file has the color depth specified in 'nColorBits'.
//
bool SaveIcon(HICON hIcon, DWORD& szSize ,int nColorBits, const TCHAR* szPath)
{
    ASSERT(nColorBits == 4 || nColorBits == 8 || nColorBits == 24 || nColorBits == 32);

    if (offsetof(ICONDIRENTRY, nOffset) != 12)
    {
       return false;
    }

    CDC dc;
    dc.Attach(::GetDC(NULL)); // ensure that DC is released when function ends
    // Open file for writing:
    CFile file;
    if (!file.Open(szPath, CFile::modeWrite | CFile::modeCreate))
    {
        return false;
    }
    // Write header:
    UCHAR icoHeader[6] = { 0, 0, 1, 0, 1, 0 }; // ICO file with 1 image
    file.Write(icoHeader, sizeof(icoHeader));
    // Get information about icon:
    ICONINFO iconInfo;
    GetIconInfo(hIcon, &iconInfo);
    CGdiHandle handle1(iconInfo.hbmColor), handle2(iconInfo.hbmMask); // free bitmaps when function ends
    BITMAPINFO bmInfo = { 0 };
    bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmInfo.bmiHeader.biBitCount = 0;    // don't get the color table     
    if (!GetDIBits(dc, iconInfo.hbmColor, 0, 0, NULL, &bmInfo, DIB_RGB_COLORS))
    {
        return false;
    }
    // Allocate size of bitmap info header plus space for color table:
    int nBmInfoSize = sizeof(BITMAPINFOHEADER);
    if (nColorBits < 24)
    {
        nBmInfoSize += sizeof(RGBQUAD) * (int)(1 << nColorBits);
    }
    CAutoVectorPtr<UCHAR> bitmapInfo;
    bitmapInfo.Allocate(nBmInfoSize);
    BITMAPINFO* pBmInfo = (BITMAPINFO*)(UCHAR*)bitmapInfo;
    memcpy(pBmInfo, &bmInfo, sizeof(BITMAPINFOHEADER));

    // Get bitmap data:
    ASSERT(bmInfo.bmiHeader.biSizeImage != 0);
    CAutoVectorPtr<UCHAR> bits;
    bits.Allocate(bmInfo.bmiHeader.biSizeImage);
    pBmInfo->bmiHeader.biBitCount = nColorBits;
    pBmInfo->bmiHeader.biCompression = BI_RGB;
    if (!GetDIBits(dc, iconInfo.hbmColor, 0, bmInfo.bmiHeader.biHeight, (UCHAR*)bits, pBmInfo, DIB_RGB_COLORS))
    {
         return false;
    }
    // Get mask data:
    BITMAPINFO maskInfo = { 0 };
    maskInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    maskInfo.bmiHeader.biBitCount = 0;  // don't get the color table     
    if (!GetDIBits(dc, iconInfo.hbmMask, 0, 0, NULL, &maskInfo, DIB_RGB_COLORS))
    {
        return false;
    }
    ASSERT(maskInfo.bmiHeader.biBitCount == 1);
    CAutoVectorPtr<UCHAR> maskBits;
    maskBits.Allocate(maskInfo.bmiHeader.biSizeImage);
    CAutoVectorPtr<UCHAR> maskInfoBytes;
    maskInfoBytes.Allocate(sizeof(BITMAPINFO) + 2 * sizeof(RGBQUAD));
    BITMAPINFO* pMaskInfo = (BITMAPINFO*)(UCHAR*)maskInfoBytes;
    memcpy(pMaskInfo, &maskInfo, sizeof(maskInfo));
    if (!GetDIBits(dc, iconInfo.hbmMask, 0, maskInfo.bmiHeader.biHeight, (UCHAR*)maskBits, pMaskInfo, DIB_RGB_COLORS))
    {
        return false;
    }
    // Write directory entry:
    ICONDIRENTRY dir;
    dir.nWidth = (UCHAR)pBmInfo->bmiHeader.biWidth;
    dir.nHeight = (UCHAR)pBmInfo->bmiHeader.biHeight;
    dir.nNumColorsInPalette = (nColorBits == 4 ? 16 : 0);
    dir.nReserved = 0;
    dir.nNumColorPlanes = 0;
    dir.nBitsPerPixel = pBmInfo->bmiHeader.biBitCount;
    dir.nDataLength = pBmInfo->bmiHeader.biSizeImage + pMaskInfo->bmiHeader.biSizeImage + nBmInfoSize;
    dir.nOffset = sizeof(dir) + sizeof(icoHeader);
    file.Write(&dir, sizeof(dir));
    // Write DIB header (including color table):
    int nBitsSize = pBmInfo->bmiHeader.biSizeImage;
    pBmInfo->bmiHeader.biHeight *= 2; // because the header is for both image and mask
    pBmInfo->bmiHeader.biCompression = 0;
    pBmInfo->bmiHeader.biSizeImage += pMaskInfo->bmiHeader.biSizeImage; // because the header is for both image and mask
    file.Write(&pBmInfo->bmiHeader, nBmInfoSize);
    // Write image data:
    file.Write((UCHAR*)bits, nBitsSize);

    // Write mask data:
    file.Write((UCHAR*)maskBits, pMaskInfo->bmiHeader.biSizeImage);
	szSize = file.GetLength();
    file.Close();
    return true;
}
Esempio n. 8
0
bool CDVDSession::ReadKey(DVD_KEY_TYPE KeyType, BYTE* pKeyData, int lba)
{
    CAutoVectorPtr<BYTE> key;
    DVD_COPY_PROTECT_KEY* pKey = nullptr;

    auto allocateKey = [&](ULONG len) {
        bool bSuccess = key.Allocate(len);
        if (bSuccess) {
            pKey = (DVD_COPY_PROTECT_KEY*)(BYTE*)key;
            pKey->KeyLength = len;
        }
        return bSuccess;
    };

    switch (KeyType) {
        case DvdChallengeKey:
            if (allocateKey(DVD_CHALLENGE_KEY_LENGTH)) {
                pKey->Parameters.TitleOffset.QuadPart = 0;
            }
            break;
        case DvdBusKey1:
            if (allocateKey(DVD_BUS_KEY_LENGTH)) {
                pKey->Parameters.TitleOffset.QuadPart = 0;
            }
            break;
        case DvdDiskKey:
            if (allocateKey(DVD_DISK_KEY_LENGTH)) {
                pKey->Parameters.TitleOffset.QuadPart = 0;
            }
            break;
        case DvdTitleKey:
            if (allocateKey(DVD_TITLE_KEY_LENGTH)) {
                pKey->Parameters.TitleOffset.QuadPart = 2048i64 * lba;
            }
            break;
        default:
            break;
    }

    if (!pKey) {
        return false;
    }

    pKey->SessionId = m_session;
    pKey->KeyType = KeyType;
    pKey->KeyFlags = 0;

    DWORD dwBytesReturned;
    if (!DeviceIoControl(m_hDrive, IOCTL_DVD_READ_KEY, pKey, pKey->KeyLength, pKey, pKey->KeyLength, &dwBytesReturned, nullptr)) {
        DWORD err = GetLastError();
        UNREFERENCED_PARAMETER(err);
        return false;
    }

    switch (KeyType) {
        case DvdChallengeKey:
            Reverse(pKeyData, pKey->KeyData, 10);
            break;
        case DvdBusKey1:
            Reverse(pKeyData, pKey->KeyData, 5);
            break;
        case DvdDiskKey:
            memcpy(pKeyData, pKey->KeyData, 2048);
            for (int i = 0; i < 2048 / 5; i++) {
                pKeyData[i] ^= m_SessionKey[4 - (i % 5)];
            }
            break;
        case DvdTitleKey:
            memcpy(pKeyData, pKey->KeyData, 5);
            for (int i = 0; i < 5; i++) {
                pKeyData[i] ^= m_SessionKey[4 - (i % 5)];
            }
            break;
        default:
            break;
    }

    return true;
}
HRESULT ThreadController::EnumeratePropertyMembers(_In_ ULONG propertyId, _In_ UINT radix, _Inout_ vector<shared_ptr<PropertyInfo>>& spPropertyInfos)
{
    ATLENSURE_RETURN_HR(ThreadHelpers::IsOnDispatchThread(m_dispatchThreadId), E_UNEXPECTED);

    // Lock the callframe access
    CComCritSecLock<CComAutoCriticalSection> lock(m_csCallFramesLock);

    if (!this->IsConnected() || !this->IsAtBreak())
    {
        return E_NOT_VALID_STATE;
    }

    auto it = m_propertyMap.find(propertyId);
    if (it != m_propertyMap.end())
    {
        CComPtr<IDebugProperty> spDebugProperty = it->second;

        // Get all the members for the children
        CComPtr<IEnumDebugPropertyInfo> spEnumProps;
        HRESULT hr = spDebugProperty->EnumMembers(PROP_INFO_ALL, radix, IID_IEnumDebugPropertyInfo, &spEnumProps);
        
        if (hr == E_NOTIMPL)
        {
            // This is reported in Watson, but we do not have a repro. Returning no properties is a 
            // better experience than failing, until we can diagnose and avoid this case.
            _ASSERT_EXPR(false, L"IEnumDebugPropertyInfo->EnumMembers returned E_NOTIMPL");
            return S_OK;
        }
        else if (hr == E_FAIL)
        {
            // The webcrawler hits an issue where the PDM returns E_FAIL. In this case we want to just
            // return an empty array back to the front end instead of asserting and blocking with a dialog.
            return S_OK;
        }

        BPT_FAIL_IF_NOT_S_OK(hr);

        hr = spEnumProps->Reset();
        BPT_FAIL_IF_NOT_S_OK(hr);

        ULONG count;
        hr = spEnumProps->GetCount(&count);
        if (hr == S_OK) // Since GetCount can fail when walking the properties, we return the hr which results in an empty array
        {
            for (ULONG i = 0; i < count; i++)
            {
                // Fetch each child one at a time, if we fail to get all of them, we can return with the successful ones
                CAutoVectorPtr<DebugPropertyInfo> spDebugPropertyInfo;
                bool alloced = spDebugPropertyInfo.Allocate(1);
                ATLENSURE_RETURN_HR(alloced == true, E_OUTOFMEMORY);

                // Fetch the next child and add it to the list
                ULONG numFetched = 0;
                hr = spEnumProps->Next(1, spDebugPropertyInfo.m_p, &numFetched);
                if (hr == S_OK && numFetched == 1) // This can fail for certain properties (e.g. location) in some conditions (e.g. a navigation), so we just ignore and continue
                {
                    // Get the property info
                    shared_ptr<PropertyInfo> spPropertyInfo;
                    hr = this->PopulatePropertyInfo(spDebugPropertyInfo[0], spPropertyInfo);
                    if (hr == S_OK)
                    {
                        // Store this to the out parameter
                        spPropertyInfos.push_back(spPropertyInfo);
                    }
                }
            }
        }
    }
    else
    {
        return E_NOT_FOUND;
    }

    return S_OK;
}
Esempio n. 10
0
bool CCDDAStream::Load(const WCHAR* fnw)
{
    CString path(fnw);

    int iDriveLetter = path.Find(_T(":\\")) - 1;
    int iTrackIndex = CString(path).MakeLower().Find(_T(".cda")) - 1;
    if (iDriveLetter < 0 || iTrackIndex <= iDriveLetter) {
        return false;
    }

    CString drive = CString(_T("\\\\.\\")) + path[iDriveLetter] + _T(":");
    while (iTrackIndex > 0 && _istdigit(path[iTrackIndex - 1])) {
        iTrackIndex--;
    }
    if (1 != _stscanf_s(path.Mid(iTrackIndex), _T("%d"), &iTrackIndex)) {
        return false;
    }

    if (m_hDrive != INVALID_HANDLE_VALUE) {
        CloseHandle(m_hDrive);
        m_hDrive = INVALID_HANDLE_VALUE;
    }

    m_hDrive = CreateFile(drive, GENERIC_READ, FILE_SHARE_READ, nullptr,
                          OPEN_EXISTING, FILE_ATTRIBUTE_READONLY | FILE_FLAG_SEQUENTIAL_SCAN, (HANDLE)nullptr);
    if (m_hDrive == INVALID_HANDLE_VALUE) {
        return false;
    }

    DWORD BytesReturned;
    if (!DeviceIoControl(m_hDrive, IOCTL_CDROM_READ_TOC, nullptr, 0, &m_TOC, sizeof(m_TOC), &BytesReturned, 0)
            || !(m_TOC.FirstTrack <= iTrackIndex && iTrackIndex <= m_TOC.LastTrack)) {
        CloseHandle(m_hDrive);
        m_hDrive = INVALID_HANDLE_VALUE;
        return false;
    }

    // MMC-3 Draft Revision 10g: Table 222 - Q Sub-channel control field
    m_TOC.TrackData[iTrackIndex - 1].Control &= 5;
    if (!(m_TOC.TrackData[iTrackIndex - 1].Control == 0 || m_TOC.TrackData[iTrackIndex - 1].Control == 1)) {
        CloseHandle(m_hDrive);
        m_hDrive = INVALID_HANDLE_VALUE;
        return false;
    }

    if (m_TOC.TrackData[iTrackIndex - 1].Control & 8) {
        m_header.frm.pcm.wf.nChannels = 4;
    }

    m_nStartSector = MSF2UINT(m_TOC.TrackData[iTrackIndex - 1].Address) - 150;
    m_nStopSector = MSF2UINT(m_TOC.TrackData[iTrackIndex].Address) - 150;

    m_llLength = LONGLONG(m_nStopSector - m_nStartSector) * RAW_SECTOR_SIZE;

    m_header.riff.hdr.chunkSize = (long)(m_llLength + sizeof(m_header) - 8);
    m_header.data.hdr.chunkSize = (long)(m_llLength);

    // Detect DTS Music Disk
    m_bDTS = false;

    // DCA syncwords
    const DWORD DCA_MARKER_RAW_BE = 0x7FFE8001;
    const DWORD DCA_MARKER_RAW_LE = 0xFE7F0180;
    const DWORD DCA_MARKER_14B_BE = 0x1FFFE800;
    const DWORD DCA_MARKER_14B_LE = 0xFF1F00E8;
    UINT nMarkerFound = 0, nAttempt = 0;
    DWORD marker = DWORD_MAX;

    std::vector<BYTE> data(16384);
    DWORD dwSizeRead = 0;
    while (SUCCEEDED(Read(data.data(), (DWORD)data.size(), TRUE, &dwSizeRead)) && dwSizeRead && nAttempt < (4 + nMarkerFound)) {
        nAttempt++;

        for (DWORD i = 0; i < dwSizeRead; i++) {
            marker = (marker << 8) | data[i];
            if ((marker == DCA_MARKER_14B_LE && (i < dwSizeRead - 2) && (data[i + 1] & 0xF0) == 0xF0 && data[i + 2] == 0x07)
                    || (marker == DCA_MARKER_14B_BE && (i < dwSizeRead - 2) && data[i + 1] == 0x07 && (data[i + 2] & 0xF0) == 0xF0)
                    || marker == DCA_MARKER_RAW_LE || marker == DCA_MARKER_RAW_BE) {
                nMarkerFound++;
            }
        }
        dwSizeRead = 0;

        if (nMarkerFound >= 4) {
            m_bDTS = true;
            break;
        }
    }
    SetPointer(0);

    CDROM_READ_TOC_EX TOCEx;
    ZeroMemory(&TOCEx, sizeof(TOCEx));
    TOCEx.Format = CDROM_READ_TOC_EX_FORMAT_CDTEXT;
    BYTE header[4] = { 0 };
    static_assert(sizeof(header) >= MINIMUM_CDROM_READ_TOC_EX_SIZE, "sizeof(header) must be greater or equal to MINIMUM_CDROM_READ_TOC_EX_SIZE");
    if (!DeviceIoControl(m_hDrive, IOCTL_CDROM_READ_TOC_EX, &TOCEx, sizeof(TOCEx), header, sizeof(header), &BytesReturned, 0)) {
        return true;
    }

    DWORD size = 2 + (WORD(header[0]) << 8) + header[1];
    if (size <= 4) { // No cd-text information
        return true;
    }

    CAutoVectorPtr<BYTE> pCDTextData;
    if (!pCDTextData.Allocate(size)) {
        return true;
    }
    ZeroMemory(pCDTextData, size);

    if (!DeviceIoControl(m_hDrive, IOCTL_CDROM_READ_TOC_EX, &TOCEx, sizeof(TOCEx), pCDTextData, size, &BytesReturned, 0)) {
        return true;
    }

    size = (WORD)(BytesReturned - sizeof(CDROM_TOC_CD_TEXT_DATA));
    CDROM_TOC_CD_TEXT_DATA_BLOCK* pDesc = ((CDROM_TOC_CD_TEXT_DATA*)(BYTE*)pCDTextData)->Descriptors;

    CStringArray str[16];
    for (int i = 0; i < _countof(str); i++) {
        str[i].SetSize(1 + m_TOC.LastTrack);
    }
    CString last;

    for (int i = 0; size >= sizeof(CDROM_TOC_CD_TEXT_DATA_BLOCK); i++, size -= sizeof(CDROM_TOC_CD_TEXT_DATA_BLOCK), pDesc++) {
        if (pDesc->TrackNumber > m_TOC.LastTrack) {
            continue;
        }

        const int lenU = _countof(pDesc->Text);
        const int lenW = _countof(pDesc->WText);

        CString text = !pDesc->Unicode
                       ? CString(CStringA((CHAR*)pDesc->Text, lenU))
                       : CString(CStringW((WCHAR*)pDesc->WText, lenW));

        int tlen = text.GetLength();
        CString tmp = (tlen < 12 - 1)
                      ? (!pDesc->Unicode
                         ? CString(CStringA((CHAR*)pDesc->Text + tlen + 1, lenU - (tlen + 1)))
                         : CString(CStringW((WCHAR*)pDesc->WText + tlen + 1, lenW - (tlen + 1))))
                      : _T("");

        if (pDesc->PackType < 0x80 || pDesc->PackType >= 0x80 + 0x10) {
            continue;
        }
        pDesc->PackType -= 0x80;

        if (pDesc->CharacterPosition == 0) {
            str[pDesc->PackType][pDesc->TrackNumber] = text;
        } else { // pDesc->CharacterPosition <= 0xf since CharacterPosition is a 4-bit field
            if (pDesc->CharacterPosition < 0xf && !last.IsEmpty()) {
                str[pDesc->PackType][pDesc->TrackNumber] = last + text;
            } else {
                str[pDesc->PackType][pDesc->TrackNumber] += text;
            }
        }

        last = tmp;
    }

    m_discTitle = str[0][0];
    m_trackTitle = str[0][iTrackIndex];
    m_discArtist = str[1][0];
    m_trackArtist = str[1][iTrackIndex];

    return true;
}
Esempio n. 11
0
bool CCDDAStream::Load(const WCHAR* fnw)
{
    CString path(fnw);

    int iDriveLetter = path.Find(_T(":\\")) - 1;
    int iTrackIndex = CString(path).MakeLower().Find(_T(".cda")) - 1;
    if (iDriveLetter < 0 || iTrackIndex <= iDriveLetter) {
        return false;
    }

    CString drive = CString(_T("\\\\.\\")) + path[iDriveLetter] + _T(":");
    while (iTrackIndex > 0 && _istdigit(path[iTrackIndex - 1])) {
        iTrackIndex--;
    }
    if (1 != _stscanf_s(path.Mid(iTrackIndex), _T("%d"), &iTrackIndex)) {
        return false;
    }

    if (m_hDrive != INVALID_HANDLE_VALUE) {
        CloseHandle(m_hDrive);
        m_hDrive = INVALID_HANDLE_VALUE;
    }

    m_hDrive = CreateFile(drive, GENERIC_READ, FILE_SHARE_READ, nullptr,
                          OPEN_EXISTING, FILE_ATTRIBUTE_READONLY | FILE_FLAG_SEQUENTIAL_SCAN, (HANDLE)nullptr);
    if (m_hDrive == INVALID_HANDLE_VALUE) {
        return false;
    }

    DWORD BytesReturned;
    if (!DeviceIoControl(m_hDrive, IOCTL_CDROM_READ_TOC, nullptr, 0, &m_TOC, sizeof(m_TOC), &BytesReturned, 0)
            || !(m_TOC.FirstTrack <= iTrackIndex && iTrackIndex <= m_TOC.LastTrack)) {
        CloseHandle(m_hDrive);
        m_hDrive = INVALID_HANDLE_VALUE;
        return false;
    }

    // MMC-3 Draft Revision 10g: Table 222 - Q Sub-channel control field
    m_TOC.TrackData[iTrackIndex - 1].Control &= 5;
    if (!(m_TOC.TrackData[iTrackIndex - 1].Control == 0 || m_TOC.TrackData[iTrackIndex - 1].Control == 1)) {
        CloseHandle(m_hDrive);
        m_hDrive = INVALID_HANDLE_VALUE;
        return false;
    }

    if (m_TOC.TrackData[iTrackIndex - 1].Control & 8) {
        m_header.frm.pcm.wf.nChannels = 4;
    }

    m_nStartSector = MSF2UINT(m_TOC.TrackData[iTrackIndex - 1].Address) - 150; //MSF2UINT(m_TOC.TrackData[0].Address);
    m_nStopSector = MSF2UINT(m_TOC.TrackData[iTrackIndex].Address) - 150;//MSF2UINT(m_TOC.TrackData[0].Address);

    m_llLength = LONGLONG(m_nStopSector - m_nStartSector) * RAW_SECTOR_SIZE;

    m_header.riff.hdr.chunkSize = (long)(m_llLength + sizeof(m_header) - 8);
    m_header.data.hdr.chunkSize = (long)(m_llLength);

    do {
        CDROM_READ_TOC_EX TOCEx;
        ZeroMemory(&TOCEx, sizeof(TOCEx));
        TOCEx.Format = CDROM_READ_TOC_EX_FORMAT_CDTEXT;
        TOCEx.SessionTrack = iTrackIndex;
        WORD size = 0;
        ASSERT(MINIMUM_CDROM_READ_TOC_EX_SIZE == sizeof(size));
        if (!DeviceIoControl(m_hDrive, IOCTL_CDROM_READ_TOC_EX, &TOCEx, sizeof(TOCEx), &size, sizeof(size), &BytesReturned, 0)) {
            break;
        }

        size = _byteswap_ushort(size) + sizeof(size);

        CAutoVectorPtr<BYTE> pCDTextData;
        if (!pCDTextData.Allocate(size)) {
            break;
        }
        ZeroMemory(pCDTextData, size);

        if (!DeviceIoControl(m_hDrive, IOCTL_CDROM_READ_TOC_EX, &TOCEx, sizeof(TOCEx), pCDTextData, size, &BytesReturned, 0)) {
            break;
        }

        size = (WORD)(BytesReturned - sizeof(CDROM_TOC_CD_TEXT_DATA));
        CDROM_TOC_CD_TEXT_DATA_BLOCK* pDesc = ((CDROM_TOC_CD_TEXT_DATA*)(BYTE*)pCDTextData)->Descriptors;

        CStringArray str[16];
        for (int i = 0; i < _countof(str); i++) {
            str[i].SetSize(1 + m_TOC.LastTrack);
        }
        CString last;

        for (int i = 0; size >= sizeof(CDROM_TOC_CD_TEXT_DATA_BLOCK); i++, size -= sizeof(CDROM_TOC_CD_TEXT_DATA_BLOCK), pDesc++) {
            if (pDesc->TrackNumber > m_TOC.LastTrack) {
                continue;
            }

            const int lenU = _countof(pDesc->Text);
            const int lenW = _countof(pDesc->WText);

            CString text = !pDesc->Unicode
                           ? CString(CStringA((CHAR*)pDesc->Text, lenU))
                           : CString(CStringW((WCHAR*)pDesc->WText, lenW));

            int tlen = text.GetLength();
            CString tmp = (tlen < 12 - 1)
                          ? (!pDesc->Unicode
                             ? CString(CStringA((CHAR*)pDesc->Text + tlen + 1, lenU - (tlen + 1)))
                             : CString(CStringW((WCHAR*)pDesc->WText + tlen + 1, lenW - (tlen + 1))))
                          : _T("");

            if (pDesc->PackType < 0x80 || pDesc->PackType >= 0x80 + 0x10) {
                continue;
            }
            pDesc->PackType -= 0x80;

            if (pDesc->CharacterPosition == 0) {
                str[pDesc->PackType][pDesc->TrackNumber] = text;
            } else { // pDesc->CharacterPosition <= 0xf since CharacterPosition is a 4-bit field
                if (pDesc->CharacterPosition < 0xf && !last.IsEmpty()) {
                    str[pDesc->PackType][pDesc->TrackNumber] = last + text;
                } else {
                    str[pDesc->PackType][pDesc->TrackNumber] += text;
                }
            }

            last = tmp;
        }

        m_discTitle = str[0][0];
        m_trackTitle = str[0][iTrackIndex];
        m_discArtist = str[1][0];
        m_trackArtist = str[1][iTrackIndex];
    } while (0);


    return true;
}