BOOL
DownloadPdbFile(const char
*
szModuleFileName, const char
*
szDownloadDir)
{
HINTERNET hInternet;
HINTERNET hConnect;
HINTERNET hRequest;
char buf[
512
];
char szGuid[
128
];
SYMSRV_INDEX_INFO info;
BOOL
bReturn
=
FALSE;
ZeroMemory(&info, sizeof(info));
info.sizeofstruct
=
sizeof(info);
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
查询模块文件的GUID信息;
if
(!SymSrvGetFileIndexInfo(szModuleFileName, &info,
0
))
{
printf(
"error : SymSrvGetFileIndexInfo:[%d]"
, GetLastError());
return
FALSE;
}
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
GUID转换为文本;
sprintf_s(szGuid, sizeof szGuid,
"%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X%X"
,
info.guid.Data1,
info.guid.Data2,
info.guid.Data3,
info.guid.Data4[
0
],
info.guid.Data4[
1
],
info.guid.Data4[
2
],
info.guid.Data4[
3
],
info.guid.Data4[
4
],
info.guid.Data4[
5
],
info.guid.Data4[
6
],
info.guid.Data4[
7
],
info.age);
printf(
"下载链接:https://msdl.microsoft.com/download/symbols/%s/%s/%s\n"
,
info.pdbfile,
szGuid,
info.pdbfile);
printf(
"下载目录:%s\n"
, szDownloadDir);
system(
"pause"
);
hInternet
=
InternetOpenW(L
"Microsoft-Symbol-Server/10.1710.0.0"
,
0
,
0
,
0
,
0
);
if
(hInternet)
{
hConnect
=
InternetConnectW(
hInternet,
L
"msdl.microsoft.com"
,
INTERNET_DEFAULT_HTTPS_PORT,
NULL,
NULL,
INTERNET_SERVICE_HTTP,
0
,
NULL);
if
(hConnect)
{
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
页面地址;
sprintf_s(
buf,
sizeof buf,
"/download/symbols/%s/%s/%s"
,
info.pdbfile,
szGuid,
info.pdbfile);
hRequest
=
HttpOpenRequestA(
hConnect,
"GET"
,
buf,
"HTTP/1.0"
,
NULL,
NULL,
INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_SECURE | INTERNET_FLAG_KEEP_CONNECTION,
NULL);
if
(hRequest)
{
DWORD dwFlags
=
0
;
DWORD dwLen
=
sizeof(dwFlags);
InternetQueryOption(
hRequest,
INTERNET_OPTION_SECURITY_FLAGS,
(LPVOID)&dwFlags,
&dwLen);
dwFlags |
=
SECURITY_FLAG_IGNORE_UNKNOWN_CA;
dwFlags |
=
SECURITY_FLAG_IGNORE_CERT_DATE_INVALID;
dwFlags |
=
SECURITY_FLAG_IGNORE_CERT_CN_INVALID;
InternetSetOption(
hRequest,
INTERNET_OPTION_SECURITY_FLAGS,
&dwFlags,
sizeof dwFlags);
printf(
"发送GET请求...\n"
);
if
(HttpSendRequestW(hRequest, NULL,
0
, NULL,
0
))
{
DWORD dwStatus
=
0
;
DWORD dwIndex
=
0
;
dwLen
=
sizeof(dwStatus);
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
获取页面返回状态;
if
(HttpQueryInfoW(
hRequest,
HTTP_QUERY_FLAG_NUMBER | HTTP_QUERY_STATUS_CODE,
&dwStatus,
&dwLen,
&dwIndex) && dwStatus
=
=
HTTP_STATUS_OK)
{
DWORD dwFileSize
=
0
;
dwLen
=
sizeof(dwFileSize);
dwIndex
=
0
;
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
获取PDB文件大小;
if
(HttpQueryInfoW(
hRequest,
HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER,
&dwFileSize,
&dwLen,
&dwIndex) && dwFileSize)
{
printf(
"文件总大小:%dKB"
, dwFileSize
/
1024
);
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
申请缓冲区;
LPVOID lpBuffer;
lpBuffer
=
VirtualAlloc(NULL, dwFileSize, MEM_COMMIT, PAGE_READWRITE);
if
(lpBuffer)
{
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/
为PDB文件创建目录;
CreateDirectoryA(szDownloadDir, NULL);
/
/
下载目录
/
/
PDB文件名;
sprintf_s(
buf,
sizeof buf,
"%s\\%s"
,
szDownloadDir,
info.pdbfile);
CreateDirectoryA(buf, NULL);
/
/
下载目录
/
/
PDB文件名
/
/
GUID;
sprintf_s(
buf,
sizeof buf,
"%s\\%s\\%s"
,
szDownloadDir,
info.pdbfile, szGuid);
CreateDirectoryA(buf, NULL);
/
/
创建一个空白的PDB文件用于写入接收到的数据;
HANDLE hFile;
sprintf_s(
buf,
sizeof buf,
"%s\\%s\\%s\\%s"
,
szDownloadDir,
info.pdbfile,
szGuid,
info.pdbfile);
hFile
=
CreateFileA(
buf,
GENERIC_READ | GENERIC_WRITE,
0
,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if
(hFile !
=
INVALID_HANDLE_VALUE)
{
DWORD dwRecvSize
=
0
;
/
/
循环获取可接收的数据大小,直到接收完成;
while
(
(InternetQueryDataAvailable(hRequest, &dwLen,
0
,
0
)) &&
dwLen &&
(dwRecvSize
+
dwLen) <
=
dwFileSize)
{
bReturn
=
TRUE;
/
/
读取数据;
if
(InternetReadFile(hRequest, (char
*
)lpBuffer
+
dwRecvSize, dwLen, &dwLen))
{
dwRecvSize
+
=
dwLen;
printf(
"下载文件:%dKB/%dKB : %d%s\r\n"
,
dwRecvSize
/
1024
,
dwFileSize
/
1024
,
(DWORD)((double)dwRecvSize
/
(double)dwFileSize
*
100.0
),
"%"
);
}
else
{
bReturn
=
FALSE;
printf(
"error : InternetReadFile:[%d]"
, GetLastError());
break
;
}
}
if
(bReturn)
{
bReturn
=
WriteFile(hFile, lpBuffer, dwRecvSize, &dwRecvSize, NULL);
if
(bReturn)
{
printf(
"下载完成!\n"
);
}
else
{
printf(
"error : WriteFile:[%d]"
, GetLastError());
}
}
CloseHandle(hFile);
}
else
printf(
"error : CreateFileA:[%d]"
, GetLastError());
VirtualFree(lpBuffer,
0
, MEM_RELEASE);
}
else
printf(
"error : VirtualAlloc:[%d]"
, GetLastError());
}
else
printf(
"error : HttpQueryInfoW.GetFileSize:[%d]"
, GetLastError());
}
else
printf(
"error : HttpQueryInfoW.GetStatus:[%d]"
, GetLastError());
}
else
printf(
"error : HttpSendRequestW:[%d]"
, GetLastError());
InternetCloseHandle(hConnect);
}
else
printf(
"error : HttpOpenRequestA:[%d]"
, GetLastError());
InternetCloseHandle(hConnect);
}
else
printf(
"error : InternetConnectW:[%d]"
, GetLastError());
InternetCloseHandle(hInternet);
}
else
printf(
"error : InternetOpenW:[%d]"
, GetLastError());
return
bReturn;
}
int
main()
{
DownloadPdbFile(
"C:\\Windows\\System\\win32k.sys"
,
"C:\\Symbols"
);
return
0
;
}