BOOL IsValidPatchFile(LPCTSTR szFilename) { // MSCF const CHAR szMagicMsu[] = {'M', 'S', 'C', 'F'}; const CHAR szMagicExe[] = {'M', 'Z'}; const int TEST_BUFFER_SIZE = 4; CHAR buffer[TEST_BUFFER_SIZE] = {0}; BOOL bMatched = FALSE; CAtlFile file; if(S_OK == file.Create(szFilename, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING) ) { if(SUCCEEDED(file.Read(buffer, TEST_BUFFER_SIZE))) { LPCTSTR szDot = _tcsrchr(szFilename, _T('.')); if(szDot) { ++szDot; if(_tcsicmp(szDot, _T("msu"))==0) { bMatched = memcmp(buffer, szMagicMsu, 4)==0; } else if(_tcsicmp(szDot, _T("exe"))==0) { bMatched = memcmp(buffer, szMagicExe, 2)==0; } else bMatched = TRUE; } } file.Close(); } return bMatched; }
BOOL file_put_contents(LPCTSTR lpszFilename, BYTE *pBuffer, INT nLen) { CAtlFile file; if( FAILED( file.Create(lpszFilename, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, CREATE_ALWAYS) ) ) return FALSE; file.Write( pBuffer, nLen ); file.Close(); return TRUE; }
void DebugTools::SelfPurecallHandler(void) { wchar_t filename[MAX_PATH]; ::GetModuleFileNameW(nullptr,filename,MAX_PATH); wcscat_s(filename,L".dmp"); ::MessageBox(nullptr,filename,L"PurecallHandler",0); CAtlFile file; file.Create(filename,FILE_WRITE_DATA,FILE_SHARE_READ,CREATE_ALWAYS); BOOL res=::MiniDumpWriteDump(::GetCurrentProcess(),::GetCurrentProcessId(),file,MiniDumpNormal,nullptr,nullptr,nullptr); file.Close(); exit(0); }
bool CDTManager::SetContiInfo( CString file,CString& url,int64& len,int& cur ) { CAtlFile f; if(ERROR_SUCCESS!=f.Create(file,FILE_GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,CREATE_ALWAYS)!=ERROR_SUCCESS) { return false; } f.Write(&len,sizeof len); f.Write(&cur,sizeof cur); f.Write(url.GetBuffer(),url.GetLength()*2+2); f.Close(); return true; }
bool CDTManager::GetContiInfo( CString file,CString& url,int64& len,int& cur ) { CAtlFile f; if(ERROR_SUCCESS!=f.Create(file,FILE_GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,OPEN_EXISTING)!=ERROR_SUCCESS) { return false; } if(ERROR_SUCCESS!=f.Read(&len,sizeof len)&&f.Read(&cur,sizeof cur)!=ERROR_SUCCESS) return false; f.Read(&cur,sizeof cur); ULONGLONG flen=0; f.GetSize(flen); wchar_t* buf=new wchar_t[((size_t)flen)/2+1]; ZeroMemory(buf,((size_t)flen)/2+1); f.Read(buf,(DWORD)flen); url=buf; delete [] buf; f.Close(); return true; }
LPVOID ReadFile(LPCTSTR pPath, DWORD *length /* = NULL */, DWORD *lengthPlusSpace /* = NULL */, DWORD spacepadding /* = 0 */, BOOL bEOF /* = FALSE */, BOOL bFailedMsgBox /* = TRUE */) { CAtlFile file; if(FAILED(file.Create(pPath, GENERIC_READ, 0, OPEN_EXISTING))) { if(bFailedMsgBox) { /*CString sMsg; sMsg.Format(IDS_ERR_FILENOTFOUND, pPath); MessageBox(NULL, sMsg, _T("ERROR"), MB_OK);*/ } return NULL; } UINT64 len64 = 0; file.GetSize(len64); if(len64 > _UI32_MAX)return NULL; DWORD len = (DWORD)len64; DWORD lenPlusSpace = len + spacepadding; if(lenPlusSpace < len) { lenPlusSpace = len; spacepadding = 0; } LPVOID p = new char[lenPlusSpace + 1]; file.Read(p, len); LPBYTE sp = ((LPBYTE)p)+lenPlusSpace-1; for(;spacepadding;spacepadding--) { *sp = ' '; sp--; } *((LPBYTE)p+lenPlusSpace) = '\0'; if(bEOF)*((LPBYTE)p+len) = 0x1a; file.Close(); if(length!=NULL)*length=len; if(lengthPlusSpace!=NULL)*lengthPlusSpace = lenPlusSpace; return p; }
BOOL file_get_contents( LPCTSTR lpszFilename, CStringA &strA ) { CAtlFile file; if( FAILED( file.Create(lpszFilename, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING) ) ) return FALSE; BOOL bRet = FALSE; do { ULONGLONG filesize = 0; if( FAILED( file.GetSize(filesize) ) ) break; strA = ""; if(filesize>0) { file.Read( strA.GetBuffer((int)filesize), (DWORD)filesize ); strA.ReleaseBuffer((int)filesize); } bRet = TRUE; } while (FALSE); file.Close(); return bRet; }
HRESULT STDMETHODCALLTYPE CSoftMgrUpdateHelper::Combine( LPCWSTR lpwszDifflib ) { #if OPEN_VCDIFF // 加载Delta BkDatLibContent delta; CDataFileLoader loader; if(!loader.GetLibDatContent(lpwszDifflib, delta)) return ::HRESULT_FROM_WIN32(ERROR_BAD_FORMAT); // 目标文件路径 wchar_t szDstPath[MAX_PATH] = {0}; { ::GetModuleFileNameW(NULL, szDstPath, MAX_PATH); ::PathRemoveFileSpecW(szDstPath); wcscat_s(szDstPath, MAX_PATH, L"\\KSoft\\Data\\"); wcscat_s(szDstPath, MAX_PATH, ::PathFindFileNameW(lpwszDifflib)); // //@Issue // 根据名称来判断库类型 // //@Note // 命名规则为:libname_old_new.dat // LPWSTR pSep = wcschr(::PathFindFileNameW(szDstPath), L'_'); if(pSep == NULL) return ::HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER); pSep[0] = L'\0'; wcscat_s(szDstPath, MAX_PATH, L".dat"); } // 加载字典文件 CAtlFile dictFile; HRESULT hr = dictFile.Create(szDstPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_EXISTING); if(!SUCCEEDED(hr)) return hr; ULONGLONG dictSize; hr = dictFile.GetSize(dictSize); if(!SUCCEEDED(hr)) return hr; auto_buffer<char> dict(static_cast<size_t>(dictSize)); if(dict.empty()) return ::HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY); DWORD bytesRead; hr = dictFile.Read(dict.data(), static_cast<DWORD>(dict.size()), bytesRead); if(!SUCCEEDED(hr)) return hr; dictFile.Close(); // 创建目标临时文件 CAtlTemporaryFile tempTarget; hr = tempTarget.Create(); if(!SUCCEEDED(hr)) return hr; // // 开始合并 // //@Note // Dict(Source) + Delta => Target // Output2File output2File(tempTarget); { VCDiffStreamingDecoder decoder; decoder.StartDecoding(&dict[0], dict.size()); size_t beg = 0; size_t end = static_cast<size_t>(delta.nLen); LPCSTR pDelta = reinterpret_cast<LPCSTR>(delta.pBuffer); while(beg < end) { static const size_t MAX_THUNK_SIZE = 16*1024; size_t size = end - beg; if(size > MAX_THUNK_SIZE) size = MAX_THUNK_SIZE; if(!decoder.DecodeChunkToInterface(pDelta + beg, size, &output2File)) return ::HRESULT_FROM_WIN32(ERROR_BAD_FORMAT); beg += size; } if(!decoder.FinishDecoding()) return ::HRESULT_FROM_WIN32(ERROR_BAD_FORMAT); } // 根据写入文件大小与期望大小来判断是否合并成功 ULONGLONG dstSize; hr = tempTarget.GetPosition(dstSize); if(!SUCCEEDED(hr) || dstSize != output2File.GetTotalBytes()) return ::HRESULT_FROM_WIN32(ERROR_WRITE_FAULT); // 移动到目标路径 return tempTarget.Close(szDstPath); #else return S_OK; #endif }
HRESULT FAsyncDownload::FHttpDownloadTP::ProcessDownload(FAsyncDownData *pData) { HRESULT hr = E_FAIL; FString ReqUrl = pData->m_pUrlInfo->m_DownloadUrl; UrlUnescapeInPlace(ReqUrl.GetBuffer(), 0); CUrl url; url.CrackUrl(ReqUrl); const tchar* pszUserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"; FHInternet hIn = NULL; if (g_AppSettings.m_Proxy.GetLength() > 0) { hIn = InternetOpen(pszUserAgent, INTERNET_OPEN_TYPE_PROXY, g_AppSettings.m_Proxy, g_AppSettings.m_ProxyA, 0); } else { hIn = InternetOpen(pszUserAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); } if (NULL == hIn) return E_HTTP_NET_ERROR; FHInternet hCon = InternetConnect(hIn, url.GetHostName(), url.GetPortNumber(), url.GetUserName(), url.GetPassword(), INTERNET_SERVICE_HTTP, 0, 0); if (NULL == hCon) { _DBGAlert("**FAsyncDownload::FHttpDownloadTP::ProcessDownload: InternetConnect() failed: %d\n", GetLastError()); return E_HTTP_NET_ERROR; } ULONG ulRecvTimeout = 15000; InternetSetOption(hCon, INTERNET_OPTION_RECEIVE_TIMEOUT, &ulRecvTimeout, sizeof(ULONG)); FString StrRes = url.GetUrlPath(); StrRes+= url.GetExtraInfo(); FHInternet hReq = HttpOpenRequest(hCon, "GET", StrRes, NULL, NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_DONT_CACHE, 0); if (NULL == hReq) { _DBGAlert("**FAsyncDownload::FHttpDownloadTP::ProcessDownload: HttpOpenRequest() failed: %d\n", GetLastError()); return E_HTTP_NET_ERROR; } size_type FileSize = 0; if (!(pData->m_pUrlInfo->m_dwDownloadFlags & HTTP_FLAG_NO_RESUME)) FileSize = GetFileSize(pData->m_pUrlInfo->m_DownloadFile); // See if file already exists on the disk. if (FileSize > 0) { FString StrRange; StrRange.Format("Range: bytes=%I64d-", FileSize); HttpAddRequestHeaders(hReq, StrRange, StrRange.GetLength(), HTTP_ADDREQ_FLAG_ADD_IF_NEW); } FString StrVersion; StrVersion.Format("LTV_VERSION: %s", g_AppSettings.m_AppVersion); HttpAddRequestHeaders(hReq, StrVersion, StrVersion.GetLength(), HTTP_ADDREQ_FLAG_ADD_IF_NEW); if (!HttpSendRequest(hReq, NULL, 0, NULL, 0)) { int err = GetLastError(); _DBGAlert("**FAsyncDownload::FHttpDownloadTP::ProcessDownload: HttpSendRequest() failed: %d (0x%x)\n", err, HRESULT_FROM_WIN32(err)); InternetCloseHandle(hCon); InternetCloseHandle(hIn); return E_HTTP_NET_ERROR; } const DWORD dwBufferSize = 8192; char pBuffer[dwBufferSize]; FHttpConnection FConn = hReq; DWORD dwStatusCode = FConn.GetStatusCode(); FString ReqContentType = pData->m_pUrlInfo->m_ContentType; pData->m_pUrlInfo->m_ContentType = FConn.GetHeader(HTTP_QUERY_CONTENT_TYPE); pData->m_pUrlInfo->m_dwStatusCode = dwStatusCode; if (!MatchContentType(ReqContentType, pData->m_pUrlInfo->m_ContentType)) { _DBGAlert("**FAsyncDownload::FHttpDownloadTP::ProcessDownload: Content type mismatch: %s/%s\n", ReqContentType, pData->m_pUrlInfo->m_ContentType); return E_NOINTERFACE; //E_NOINTERFACE = content type mismatch } if (dwStatusCode == 416 && FileSize > 0) { _DBGAlert("FAsyncDownload::FHttpDownloadTP::ProcessDownload: Server status code: %d. Download complete\n", dwStatusCode); return S_OK; } if (dwStatusCode < 200 || dwStatusCode > 206) { _DBGAlert("**FAsyncDownload::FHttpDownloadTP::ProcessDownload: Server status code: %d\n", dwStatusCode); if (dwStatusCode == 404) return E_HTTP_NOTFOUND; return E_HTTP_INVALID_STATUS; } CAtlFile OutFile; if (pData->m_pUrlInfo->m_dwDownloadFlags & HTTP_FLAG_NO_RESUME) DeleteFile(pData->m_pUrlInfo->m_DownloadFile); hr = OutFile.Create(pData->m_pUrlInfo->m_DownloadFile, GENERIC_WRITE, 0, OPEN_ALWAYS); if (FAILED(hr)) { _DBGAlert("**FAsyncDownload::FHttpDownloadTP::ProcessDownload: CreateFile failed: 0x%x, %d : %s\n", hr, GetLastError(), pData->m_pUrlInfo->m_DownloadFile); return E_HTTP_WRITE_FILE; } size_type llTotalRead = 0; size_type llSizeMax = 0; size_type ContentLen = FConn.GetContentLength(); pData->m_pUrlInfo->m_ContentLength = ContentLen; if (dwStatusCode == 206) { FString FStrRange = FConn.GetHeader(HTTP_QUERY_CONTENT_RANGE); if (FStrRange) { //Content-Range: bytes 21010-47021/47022 const char* pszBytes = strstr(FStrRange, "bytes "); if (pszBytes != NULL) { pszBytes+=sizeof("bytes"); LONGLONG llOffset = _strtoi64(pszBytes, NULL, 10); hr = OutFile.Seek(llOffset, FILE_BEGIN); llTotalRead = (size_type)llOffset; if (FAILED(hr)) { _DBGAlert("**FAsyncDownload::FHttpDownloadTP::ProcessDownload: Seek to position %d failed: 0x%x, %d\n", hr, GetLastError()); } const char* pszTotal = strchr(pszBytes, '/'); if (pszTotal != NULL) llSizeMax = _strtoi64(pszTotal + 1, NULL, 10); } } } else { if (ContentLen > 0 && ContentLen == FileSize) { OutFile.Close(); return S_OK; } } if (llSizeMax == 0) llSizeMax = ContentLen; pData->pBindStatusCallback.OnProgress((ULONG)llTotalRead, (ULONG)llSizeMax, BINDSTATUS_BEGINDOWNLOADDATA, L""); DWORD dwBytesRead = 0; for (;;) { if (!InternetReadFile(hReq, pBuffer, dwBufferSize, &dwBytesRead)) { _DBGAlert("**FAsyncDownload::FHttpDownloadTP::ProcessDownload: InternetReadFile() failed: %d\n", GetLastError()); OutFile.Close(); return E_HTTP_NET_ERROR; } if (dwBytesRead == 0) { hr = S_OK; break; } DWORD dwBytesWritten = 0; hr = OutFile.Write(pBuffer, dwBytesRead, &dwBytesWritten); if (FAILED(hr)) { _DBGAlert("**FAsyncDownload::FHttpDownloadTP::ProcessDownload: FileWrite failed: 0x%x, %d\n", hr, GetLastError()); OutFile.Close(); return E_HTTP_WRITE_FILE; } llTotalRead+=dwBytesRead; pData->pBindStatusCallback.OnProgress((ULONG)llTotalRead, llSizeMax > 0 ? (ULONG)llSizeMax : llTotalRead , BINDSTATUS_DOWNLOADINGDATA, L""); if (m_pThis->m_Stopping || pData->pBindStatusCallback.m_Abort) { _DBGAlert("**FAsyncDownload::FHttpDownloadTP::ProcessDownload: Download aborted\n", hr, GetLastError()); hr = E_ABORT; break; } } OutFile.Close(); return hr; }
BOOL CLocalFileDownload::Fetch( INT nCorrurent/*=0*/ ) { m_bStopped = FALSE; try { CFileInStream fin(m_strUrl); if(!fin.Create()) { m_errCode = DLLER_SERVER_FILENOTFOUND; return FALSE; } CString strTmpFile; strTmpFile.Format(_T("%s%s"), m_strFilePath, _T(".tc")); CAtlFile file; if( FAILED( file.Create(strTmpFile, GENERIC_WRITE, FILE_SHARE_WRITE, CREATE_ALWAYS) ) ) { m_errCode = DLERR_CREATEFILE; return FALSE; } m_errCode = DLERR_SUCCESS; m_FileInfo.Reset(fin.GetFileSize(), 0, TRUE); m_DownStat.OnDownBegin(); int64 lastDownloaded = 0, downloadedPercent = m_FileInfo.fileSize/100; const int nBufferSize = 1024; BYTE *pBuffer = new BYTE[nBufferSize]; while(!m_bStopped) { DWORD dwReaded = 0; fin.Read(pBuffer, nBufferSize, &dwReaded); if(dwReaded==0) break; DWORD dwWrited = 0; if( FAILED(file.Write(pBuffer, dwReaded, &dwWrited)) || dwWrited!=dwReaded) { m_errCode = DLERR_WRITEFILE; break; } m_FileInfo.fileDownloaded += dwReaded; if((m_FileInfo.fileDownloaded-lastDownloaded) > downloadedPercent) { m_DownStat.OnDownData(GetTickCount(), (m_FileInfo.fileDownloaded-lastDownloaded)); lastDownloaded = m_FileInfo.fileDownloaded; _Notify(ProcessState_ReceiveData); } } fin.CloseFile(); file.Close(); SAFE_DELETE_ARRAY(pBuffer); m_DownStat.OnDownEnd(); if(m_FileInfo.fileDownloaded==m_FileInfo.fileSize) { MoveFileEx(strTmpFile, m_strFilePath, MOVEFILE_REPLACE_EXISTING); m_errCode = DLERR_SUCCESS; } else { DeleteFile(strTmpFile); m_errCode = DLLER_NETWORK; } } catch (...) { m_errCode = DLERR_WRITEFILE; } return DLERR_SUCCESS==m_errCode; }
bool CTrueType::GetProperties(LPCTSTR pszFilePath, TTF_PROPERTIES* pProperties) { CAtlFile FontFile; HRESULT hr = FontFile.Create(pszFilePath, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING); if (FAILED(hr)) return false; TTF_OFFSET_TABLE ttOffsetTable; FontFile.Read(&ttOffsetTable, sizeof(TTF_OFFSET_TABLE)); ttOffsetTable.uNumOfTables = SWAPWORD(ttOffsetTable.uNumOfTables); ttOffsetTable.uMajorVersion = SWAPWORD(ttOffsetTable.uMajorVersion); ttOffsetTable.uMinorVersion = SWAPWORD(ttOffsetTable.uMinorVersion); // See if this is a true type font and the version is 1.0 if (ttOffsetTable.uMajorVersion != 1 || ttOffsetTable.uMinorVersion != 0) return false; TTF_TABLE_DIRECTORY tblDir; TTF_TABLE_DIRECTORY tblName; TTF_TABLE_DIRECTORY tblOS2; bool bFoundNameTable = false; bool bFoundOS2Table = false; for (int i=0; i< ttOffsetTable.uNumOfTables; i++) { FontFile.Read(&tblDir, sizeof(TTF_TABLE_DIRECTORY)); CString strName = CString(tblDir.szTag, 4); if (strName.IsEmpty()) break; if (!strName.CompareNoCase("name")) { bFoundNameTable = true; tblName = tblDir; tblName.uLength = SWAPLONG(tblName.uLength); tblName.uOffset = SWAPLONG(tblName.uOffset); } else if (!strName.CompareNoCase("OS/2")) { bFoundOS2Table = true; tblOS2 = tblDir; tblOS2.uLength = SWAPLONG(tblOS2.uLength); tblOS2.uOffset = SWAPLONG(tblOS2.uOffset); } if (bFoundNameTable && bFoundOS2Table) break; } if (bFoundNameTable) { FontFile.Seek(tblName.uOffset, FILE_BEGIN); TTF_NAME_TABLE_HEADER ttNTHeader; FontFile.Read(&ttNTHeader, sizeof(TTF_NAME_TABLE_HEADER)); ttNTHeader.uFSelector = SWAPWORD(ttNTHeader.uFSelector); ttNTHeader.uNRCount = SWAPWORD(ttNTHeader.uNRCount); ttNTHeader.uStorageOffset = SWAPWORD(ttNTHeader.uStorageOffset); for (int i=0; i<ttNTHeader.uNRCount; i++) { TTF_NAME_RECORD ttRecord; FontFile.Read(&ttRecord, sizeof(TTF_NAME_RECORD)); ttRecord.uPlatformID = SWAPWORD(ttRecord.uPlatformID); ttRecord.uEncodingID = SWAPWORD(ttRecord.uEncodingID); ttRecord.uLanguageID = SWAPWORD(ttRecord.uLanguageID); ttRecord.uNameID = SWAPWORD(ttRecord.uNameID); ttRecord.uStringLength = SWAPWORD(ttRecord.uStringLength); ttRecord.uStringOffset = SWAPWORD(ttRecord.uStringOffset); if (ttRecord.uPlatformID != 3) // Microsoft continue; ULONGLONG nPos = 0; FontFile.GetPosition(nPos); FontFile.Seek(tblName.uOffset + ttRecord.uStringOffset + ttNTHeader.uStorageOffset, FILE_BEGIN); int iUnicodeChars = (ttRecord.uStringLength + 1) / 2; WCHAR* pUnicodeBuffer = new WCHAR[iUnicodeChars]; FontFile.Read(pUnicodeBuffer, ttRecord.uStringLength); for (int i = 0; i < iUnicodeChars; i++) pUnicodeBuffer[i] = SWAPWORD(pUnicodeBuffer[i]); CString strName = CString(pUnicodeBuffer, iUnicodeChars); delete [] pUnicodeBuffer; FontFile.Seek(nPos, FILE_BEGIN); if (strName.IsEmpty()) continue; switch (ttRecord.uNameID) { case 1: // Font family pProperties->strFamily.IsEmpty() ? pProperties->strFamily = strName : void(); break; case 0: // Copyright notice pProperties->strCopyright.IsEmpty() ? pProperties->strCopyright = strName : void(); break; case 7: // Trademark notice pProperties->strTrademark.IsEmpty() ? pProperties->strTrademark = strName : void(); break; case 4: // Full Name of the Font pProperties->strName.IsEmpty() ? pProperties->strName = strName : void(); break; case 2: // Font sub family case 3: // Unique Family Identifier case 5: // Version of the name table case 6: // PostScript name of the font default: { break; } } } } if (bFoundOS2Table) { FontFile.Seek(tblOS2.uOffset, FILE_BEGIN); TTF_OS2_TABLE ttNTHeader; FontFile.Read(&ttNTHeader, sizeof(TTF_OS2_TABLE)); ttNTHeader.uVersion = SWAPWORD(ttNTHeader.uVersion); ttNTHeader.uAverageCharWidth = SWAPWORD(ttNTHeader.uAverageCharWidth); ttNTHeader.uWeightClass = SWAPWORD(ttNTHeader.uWeightClass); ttNTHeader.uWidthClass = SWAPWORD(ttNTHeader.uWidthClass); ttNTHeader.uFsType = SWAPWORD(ttNTHeader.uFsType); if (ttNTHeader.uFsType & 0x0001) // 1: reserved - must be zero; if not, turn it off ttNTHeader.uFsType &= ~0x0001; if (ttNTHeader.uFsType == 0x0000) // 0: embedding and permanent installation allowed { pProperties->strEmbed = "Installable"; pProperties->enumEmbed = TTF_Embed_Installable; } else if (ttNTHeader.uFsType & 0x0008) // 8: editable embedding allowed { pProperties->strEmbed = "Editable"; pProperties->enumEmbed = TTF_Embed_Editable; } else if (ttNTHeader.uFsType & 0x0004) // 4: preview and print embedding allowed { pProperties->strEmbed = "Printable"; pProperties->enumEmbed = TTF_Embed_Printable; } else if (ttNTHeader.uFsType & 0x0002) { pProperties->strEmbed = "None"; // 2: no embedding allowed pProperties->enumEmbed = TTF_Embed_None; } else { pProperties->strEmbed.Format("%d", ttNTHeader.uFsType); // unknown pProperties->enumEmbed = TTF_Embed_Unknown; } } FontFile.Close(); return !pProperties->strName.IsEmpty(); }