IE Cache 경로를 변경하는 것은 문서화되어 있지 않으며, 분석을 통해서 진행하였습니다.
( 레지스트리 값을 바꾸는 방식이 아니라 인터넷 옵션에서 바로 변경하는 방식 )
분석 된 코드를 올립니다. ( Windows XP용 )
추가적인 내용은 아래에 주소에서 찾을 수 있습니다.
http://msdn.microsoft.com/en-us/library/ms905660.aspx
/*
인터넷 익스폴로러 등록정보에서 캐시폴더의 위치를 변경하면 다음과 같은 함수를 이용하여 변경을 합니다.
그러나 UpdateUrlCacheContentPath 함수가 Undocumented 되어 있으며 그냥 Undocumented되어 있는정도가 아니라
이 함수를 사용하는 어떠한 정보도 MS및 구글에 없습니다. ReactOS에도 없습니다.
다행이 인자가 엄청나게 간단해서 함수를 호출하는 방법을 알 수 있었습니다.
UpdateUrlCacheContentPath 함수를 호출할때의 스택입니다.
이 함수는 완전히 Undocumented 되어 있는 함수입니다.
0007D664 69488538 RETURN to inetcpl.69488538 from inetcpl.6948EC10
0007D668 0007DEB4 ASCII "E:\Temporary Internet Files" ( 유니코드가 아닙니다. 그냥 아스키문자열입니다. )
0007D66C 00000001
0007D670 00000000
0007D674 000BDB98
0007D678 00000001
0007D67C 00000013
0007D680 00000000
0007D684 00000002
0007D688 00000280
0007D68C 005AE668
0007D690 0007D6D4
// UpdateUrlCacheContentPath 다음과 같은 방식으로 호출합니다.
// 이전에도 말햇듯이 이 함수는 완전히 Undocumented 되어 있는 함수이므로 어떠한 문서에도 이 함수사용방법이 나와 있지 않습니다.
6948EC0B CC INT3
6948EC0C CC INT3
6948EC0D CC INT3
6948EC0E CC INT3
6948EC0F CC INT3
6948EC10 8BFF MOV EDI,EDI
6948EC12 55 PUSH EBP
6948EC13 8BEC MOV EBP,ESP
6948EC15 A1 A02D4A69 MOV EAX,DWORD PTR DS:[694A2DA0]
6948EC1A 85C0 TEST EAX,EAX
6948EC1C 75 1B JNZ SHORT inetcpl.6948EC39
6948EC1E 68 28264869 PUSH inetcpl.69482628 ; ASCII "WININET.DLL"
6948EC23 FF15 68104869 CALL DWORD PTR DS:[<&KERNEL32.LoadLibrar>; kernel32.LoadLibraryA
6948EC29 33C9 XOR ECX,ECX
6948EC2B 85C0 TEST EAX,EAX
6948EC2D 0F95C1 SETNE CL
6948EC30 A3 A02D4A69 MOV DWORD PTR DS:[694A2DA0],EAX
6948EC35 85C9 TEST ECX,ECX
6948EC37 74 22 JE SHORT inetcpl.6948EC5B
6948EC39 8B0D DC2D4A69 MOV ECX,DWORD PTR DS:[694A2DDC] ; WININET.UpdateUrlCacheContentPath
6948EC3F 85C9 TEST ECX,ECX
6948EC41 75 1E JNZ SHORT inetcpl.6948EC61
6948EC43 68 AC264869 PUSH inetcpl.694826AC ; ASCII "UpdateUrlCacheContentPath"
6948EC48 50 PUSH EAX
6948EC49 FF15 08114869 CALL DWORD PTR DS:[<&KERNEL32.GetProcAdd>; kernel32.GetProcAddress
6948EC4F 8BC8 MOV ECX,EAX
6948EC51 85C9 TEST ECX,ECX
6948EC53 890D DC2D4A69 MOV DWORD PTR DS:[694A2DDC],ECX
6948EC59 75 06 JNZ SHORT inetcpl.6948EC61
6948EC5B 33C0 XOR EAX,EAX
6948EC5D 5D POP EBP
6948EC5E C2 0400 RETN 4
6948EC61 5D POP EBP
6948EC62 FFE1 JMP ECX
6948EC64 CC INT3
6948EC65 CC INT3
6948EC66 CC INT3
6948EC67 CC INT3
6948EC68 CC INT3
// 위 함수에 리턴타입은 void 형인 것 같으며. ( 아직 확실하지 않음.. ) 인자는 PCHAR를 인자로 받습니다.
// 6948EC62 FFE1 JMP ECX ( JMP [WININET.UpdateUrlCacheContentPath] )
// 이 부분이 이 함수를 호출하는 부분입니다.
// 그러나 CALL 명령어로 해야맞는걸로 알고 있습니다.
// 위에서는 직접 CALL명령어 자체를 구현하고 있는 것으로 보이며 XP SP3에서는 바로 CALL를 합니다.
*/
void WalkCache()
{
// 중국넘들이 작성한 소스코드입니다.
// 그냥 URL캐시 리스트를 출력하는 코드이지만 Undocumented된 API를 호출하기 위해서
// 반드시 필요합니다.
BYTE byBuffer[20480];
LPINTERNET_CACHE_ENTRY_INFO lpInfo = LPINTERNET_CACHE_ENTRY_INFO(byBuffer);
DWORD dwSize = sizeof(byBuffer);
lpInfo->dwStructSize = sizeof(INTERNET_CACHE_ENTRY_INFO);
HANDLE h;
BOOL bSuccess = TRUE;
for (h = FindFirstUrlCacheEntryEx(NULL, 0, URLCACHE_FIND_DEFAULT_FILTER, 0, lpInfo, &dwSize, 0, 0, 0); h && bSuccess; bSuccess = FindNextUrlCacheEntryEx(h, lpInfo, &dwSize, 0, 0, 0))
{
dwSize = sizeof(byBuffer);
TRACE("%s\n", lpInfo->lpszSourceUrlName);
}
FindCloseUrlCache(h);
}
typedef int (__stdcall *UpdateUrlCacheContentPath)(CHAR *lpPath);
BOOL SetInternetExplorerCacheFolder(CString strPath, BOOL bBackup)
{
HMODULE hModule;
UpdateUrlCacheContentPath pUpdateUrlCacheContentPath;
BOOL bResult;
bResult = TRUE;
if (strPath.GetLength() > 3)
{
if (strPath.Right(1) == _T("\\"))
{
strPath = strPath.Left(strPath.GetLength() - 1);
}
}
CStringA strAPath;
hModule = ::LoadLibrary(_T("wininet.dll"));
if (hModule == NULL)
{
return FALSE;
}
pUpdateUrlCacheContentPath = (UpdateUrlCacheContentPath)::GetProcAddress(hModule, "UpdateUrlCacheContentPath");
if (pUpdateUrlCacheContentPath == NULL)
{
::FreeLibrary(hModule);
return FALSE;
}
strAPath = strPath;
// 주의 !! 이 함수 ( WalkCache )는 단순히 URL캐시를 출력하기 위한 용도로 호출하는 것이 아닙니다.
// UpdateUrlCacheContentPath함수를 호출하기전에 반드시 이 함수를 호출해주어야 합니다.
// UpdateUrlCacheContentPath함수 내부적으로 글로벌 전역변수가 선언되어 있고 이 함수를 호출 시
// ECX레지스트리에 그 값을 저장하여 추후에 그 값을 액세스하게 됩니다.
// 그러나 이 값은 NULL포인터를 기본적으로 갖고 있으며 WalkCache()함수를 호출해야 이값이 어떠한 포인터값을 가지게 됩니다.
// 따라서 WalkCache와 UpdateUrlCacheContentPath함수는 하나에 통합된 함수라고 봐도 될 것 입니다.
// MS쪽에서 보자면 상당히 지저분하게 만들어진 Undocumented 된 API라고 볼 수 있습니다.
// UpdateUrlCacheContentPath함수는 모듈화가 전혀되어 있지 않습니다.
// 단, XP SP3이상부터는 모듈화가 되어 있어서 UpdateUrlCacheContentPath이 함수하나만 호출하여도 동작합니다.
WalkCache();
pUpdateUrlCacheContentPath(strAPath.GetBuffer());
::FreeLibrary(hModule);
return TRUE;
}