#include "socketwrapper.h"\r
#include "protectprocess.h"\r
#include "mbswrapper.h"\r
+#include "apiemulator.h"\r
\r
typedef struct\r
{\r
{\r
DWORD Version;\r
CHAR VersionString[32];\r
+ CHAR Description[1024];\r
DWORD FileCount;\r
UPDATE_LIST_FILE File[1];\r
} UPDATE_LIST;\r
\r
+#define UPDATE_MAX_LIST_SIZE 1048576\r
+#define UPDATE_MAX_FILE_SIZE 16777216\r
+\r
BOOL ReadFileViaHTTPW(void* pOut, DWORD Length, DWORD* pLength, LPCWSTR UserAgent, LPCWSTR ServerName, LPCWSTR ObjectName)\r
{\r
BOOL bResult;\r
{\r
if(WriteFile(hFile, pData, Size, &Size, NULL))\r
{\r
- if(SetFileTime(hFile, NULL, NULL, pTimestamp))\r
+ if(pTimestamp)\r
+ {\r
+ if(SetFileTime(hFile, NULL, NULL, pTimestamp))\r
+ bResult = TRUE;\r
+ }\r
+ else\r
bResult = TRUE;\r
}\r
CloseHandle(hFile);\r
return bResult;\r
}\r
\r
+BOOL LoadMemoryFromFileWithTimestamp(LPCTSTR FileName, void* pData, DWORD Size, DWORD* pReadSize, FILETIME* pTimestamp)\r
+{\r
+ BOOL bResult;\r
+ HANDLE hFile;\r
+ LARGE_INTEGER li;\r
+ bResult = FALSE;\r
+ if((hFile = CreateFile(FileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE)\r
+ {\r
+ if(GetFileSizeEx(hFile, &li))\r
+ {\r
+ if(li.QuadPart <= (LONGLONG)Size)\r
+ {\r
+ if(ReadFile(hFile, pData, Size, pReadSize, NULL))\r
+ {\r
+ if(*pReadSize == li.LowPart)\r
+ {\r
+ if(pTimestamp)\r
+ {\r
+ if(GetFileTime(hFile, NULL, NULL, pTimestamp))\r
+ bResult = TRUE;\r
+ }\r
+ else\r
+ bResult = TRUE;\r
+ }\r
+ }\r
+ }\r
+ CloseHandle(hFile);\r
+ }\r
+ }\r
+ return bResult;\r
+}\r
+\r
BOOL CopyAllFilesInDirectory(LPCTSTR From, LPCTSTR To)\r
{\r
BOOL bResult;\r
return bResult;\r
}\r
\r
+DWORD ListUpdateFile(UPDATE_LIST* pList, DWORD MaxCount, LPCTSTR ServerPath, LPCTSTR ReferenceDir, LPCTSTR Path)\r
+{\r
+ DWORD Result;\r
+ TCHAR Temp1[MAX_PATH];\r
+ TCHAR Temp2[MAX_PATH];\r
+ TCHAR Temp3[MAX_PATH];\r
+ HANDLE hFind;\r
+ WIN32_FIND_DATA Find;\r
+ void* pBuf;\r
+ DWORD Length;\r
+ FILETIME Time;\r
+ BYTE Hash[64];\r
+ Result = 0;\r
+ if(!Path)\r
+ Path = _T("");\r
+ if(_tcslen(ReferenceDir) + _tcslen(Path) + _tcslen(_T("\\*")) < MAX_PATH)\r
+ {\r
+ _tcscpy(Temp1, ReferenceDir);\r
+ _tcscat(Temp1, Path);\r
+ _tcscat(Temp1, _T("\\*"));\r
+ if((hFind = FindFirstFile(Temp1, &Find)) != INVALID_HANDLE_VALUE)\r
+ {\r
+ do\r
+ {\r
+ if(_tcscmp(Find.cFileName, _T(".")) != 0 && _tcscmp(Find.cFileName, _T("..")) != 0)\r
+ {\r
+ if(_tcslen(ServerPath) + _tcslen(_T("/")) + _tcslen(Find.cFileName) < 128 && _tcslen(Path) + _tcslen(_T("\\")) + _tcslen(Find.cFileName) < 128)\r
+ {\r
+ _tcscpy(Temp1, ServerPath);\r
+ _tcscat(Temp1, _T("/"));\r
+ _tcscat(Temp1, Find.cFileName);\r
+ _tcscpy(Temp2, Path);\r
+ _tcscat(Temp2, _T("\\"));\r
+ _tcscat(Temp2, Find.cFileName);\r
+ if(_tcslen(ReferenceDir) + _tcslen(Temp2) < MAX_PATH)\r
+ {\r
+ _tcscpy(Temp3, ReferenceDir);\r
+ _tcscat(Temp3, Temp2);\r
+ if((Find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))\r
+ {\r
+ if(!(Find.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT))\r
+ {\r
+ if(pList)\r
+ {\r
+ memset(&pList->File[pList->FileCount], 0, sizeof(UPDATE_LIST_FILE));\r
+ pList->File[pList->FileCount].Flags = UPDATE_LIST_FILE_FLAG_DIRECTORY;\r
+ _tcscpy(pList->File[pList->FileCount].DstPath, Temp2);\r
+ pList->FileCount++;\r
+ }\r
+ Result++;\r
+ if(Result >= MaxCount)\r
+ break;\r
+ Result += ListUpdateFile(pList, MaxCount, Temp1, ReferenceDir, Temp2);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if(pList)\r
+ {\r
+ if(pBuf = malloc(UPDATE_MAX_FILE_SIZE))\r
+ {\r
+ if(LoadMemoryFromFileWithTimestamp(Temp3, pBuf, UPDATE_MAX_FILE_SIZE, &Length, &Time))\r
+ {\r
+ if(GetHashSHA512(pBuf, Length, &Hash))\r
+ {\r
+ memset(&pList->File[pList->FileCount], 0, sizeof(UPDATE_LIST_FILE));\r
+ _tcscpy(pList->File[pList->FileCount].SrcPath, Temp1);\r
+ memcpy(&pList->File[pList->FileCount].SrcHash, &Hash, 64);\r
+ _tcscpy(pList->File[pList->FileCount].DstPath, Temp2);\r
+ pList->File[pList->FileCount].Timestamp = Time;\r
+ pList->FileCount++;\r
+ }\r
+ }\r
+ free(pBuf);\r
+ }\r
+ }\r
+ Result++;\r
+ if(Result >= MaxCount)\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ while(FindNextFile(hFind, &Find));\r
+ FindClose(hFind);\r
+ }\r
+ }\r
+ return Result;\r
+}\r
+\r
+// FFFTPの更新情報を作成\r
+BOOL BuildUpdates(LPCTSTR PrivateKeyFile, LPCTSTR Password, LPCTSTR ServerPath, LPCTSTR HashFile, LPCTSTR ListFile, DWORD Version, LPCTSTR VersionString, LPCTSTR Description)\r
+{\r
+ BOOL bResult;\r
+ char PrivateKey[4096];\r
+ DWORD Length;\r
+ TCHAR Name[MAX_PATH];\r
+ TCHAR* p;\r
+ UPDATE_LIST* pList;\r
+ UPDATE_HASH Hash;\r
+ BYTE Buf[1024];\r
+ bResult = FALSE;\r
+ memset(PrivateKey, 0, sizeof(PrivateKey));\r
+ if(LoadMemoryFromFileWithTimestamp(PrivateKeyFile, &PrivateKey, sizeof(PrivateKey) - sizeof(char), &Length, NULL))\r
+ {\r
+ if(GetModuleFileName(NULL, Name, MAX_PATH) > 0)\r
+ {\r
+ if(p = _tcsrchr(Name, _T('\\')))\r
+ *p = _T('\0');\r
+ if(pList = (UPDATE_LIST*)malloc(UPDATE_MAX_LIST_SIZE))\r
+ {\r
+ memset(pList, 0, UPDATE_MAX_LIST_SIZE);\r
+ pList->Version = Version;\r
+ _tcscpy(pList->VersionString, VersionString);\r
+ _tcscpy(pList->Description, Description);\r
+ ListUpdateFile(pList, (UPDATE_MAX_LIST_SIZE - sizeof(UPDATE_LIST)) / sizeof(UPDATE_LIST_FILE) + 1, ServerPath, Name, NULL);\r
+ Length = (pList->FileCount - 1) * sizeof(UPDATE_LIST_FILE) + sizeof(UPDATE_LIST);\r
+ if(SaveMemoryToFileWithTimestamp(ListFile, pList, Length, NULL))\r
+ {\r
+ memcpy(&Hash.Signature, UPDATE_SIGNATURE, 64);\r
+ if(GetHashSHA512(pList, Length, &Hash.ListHash))\r
+ {\r
+ if(EncryptSignature(PrivateKey, Password, &Hash, sizeof(UPDATE_HASH), &Buf, sizeof(Buf), &Length))\r
+ {\r
+ if(SaveMemoryToFileWithTimestamp(HashFile, &Buf, Length, NULL))\r
+ bResult = TRUE;\r
+ }\r
+ }\r
+ }\r
+ free(pList);\r
+ }\r
+ }\r
+ }\r
+ return bResult;\r
+}\r
+\r
// FFFTPの更新情報を確認\r
-BOOL CheckForUpdates(BOOL bDownload, LPCTSTR DownloadDir, DWORD* pVersion, LPTSTR pVersionString)\r
+BOOL CheckForUpdates(BOOL bDownload, LPCTSTR DownloadDir, DWORD* pVersion, LPTSTR pVersionString, LPTSTR pDescription)\r
{\r
BOOL bResult;\r
DWORD Length;\r
- BYTE Buf1[65536];\r
+ BYTE Buf1[1024];\r
BYTE Buf2[1024];\r
+ void* pBuf;\r
UPDATE_HASH UpdateHash;\r
BYTE Hash[64];\r
UPDATE_LIST* pUpdateList;\r
bResult = FALSE;\r
if(ReadFileViaHTTP(&Buf1, sizeof(Buf1), &Length, HTTP_USER_AGENT, UPDATE_SERVER, UPDATE_HASH_PATH))\r
{\r
- if(DecryptSignature(UPDATE_RSA_PUBLIC_KEY, &Buf1, Length, &Buf2, sizeof(Buf2), &Length))\r
+ if(DecryptSignature(UPDATE_RSA_PUBLIC_KEY, NULL, &Buf1, Length, &Buf2, sizeof(Buf2), &Length))\r
{\r
if(Length == sizeof(UPDATE_HASH))\r
{\r
memcpy(&UpdateHash, &Buf2, sizeof(UPDATE_HASH));\r
if(memcmp(&UpdateHash.Signature, UPDATE_SIGNATURE, 64) == 0)\r
{\r
- if(ReadFileViaHTTP(&Buf1, sizeof(Buf1), &Length, HTTP_USER_AGENT, UPDATE_SERVER, UPDATE_LIST_PATH))\r
+ if(pBuf = malloc(UPDATE_MAX_LIST_SIZE))\r
{\r
- GetHashSHA512(&Buf1, Length, &Hash);\r
- if(memcmp(&Hash, &UpdateHash.ListHash, 64) == 0)\r
+ if(ReadFileViaHTTP(pBuf, UPDATE_MAX_LIST_SIZE, &Length, HTTP_USER_AGENT, UPDATE_SERVER, UPDATE_LIST_PATH))\r
{\r
- if(Length >= sizeof(UPDATE_LIST))\r
+ if(GetHashSHA512(pBuf, Length, &Hash))\r
{\r
- bResult = TRUE;\r
- pUpdateList = (UPDATE_LIST*)&Buf1;\r
- if(pUpdateList->Version > *pVersion)\r
+ if(memcmp(&Hash, &UpdateHash.ListHash, 64) == 0)\r
{\r
- *pVersion = pUpdateList->Version;\r
- _tcscpy(pVersionString, pUpdateList->VersionString);\r
+ if(Length >= sizeof(UPDATE_LIST))\r
+ {\r
+ bResult = TRUE;\r
+ pUpdateList = (UPDATE_LIST*)pBuf;\r
+ if(pUpdateList->Version > *pVersion)\r
+ {\r
+ *pVersion = pUpdateList->Version;\r
+ _tcscpy(pVersionString, pUpdateList->VersionString);\r
+ _tcscpy(pDescription, pUpdateList->Description);\r
+ }\r
+ if(bDownload)\r
+ bResult = PrepareUpdates(pBuf, Length, DownloadDir);\r
+ }\r
}\r
- if(bDownload)\r
- bResult = PrepareUpdates(&Buf1, Length, DownloadDir);\r
}\r
}\r
+ free(pBuf);\r
}\r
}\r
}\r
BOOL bResult;\r
UPDATE_LIST* pUpdateList;\r
void* pBuf;\r
+ TCHAR LocalDir[MAX_PATH];\r
+ TCHAR* p;\r
DWORD i;\r
BOOL b;\r
+ TCHAR Path[MAX_PATH];\r
DWORD Length;\r
BYTE Hash[64];\r
- TCHAR Path[MAX_PATH];\r
bResult = FALSE;\r
if(ListLength >= sizeof(UPDATE_LIST))\r
{\r
bResult = TRUE;\r
DeleteDirectoryAndContents(DownloadDir);\r
CreateDirectory(DownloadDir, NULL);\r
- pBuf = malloc(16777216);\r
- for(i = 0; i < pUpdateList->FileCount; i++)\r
+ if(pBuf = malloc(UPDATE_MAX_FILE_SIZE))\r
{\r
- b = FALSE;\r
- if(pUpdateList->File[i].Flags & UPDATE_LIST_FILE_FLAG_DIRECTORY)\r
+ if(GetModuleFileName(NULL, LocalDir, MAX_PATH) > 0)\r
{\r
- _tcscpy(Path, DownloadDir);\r
- _tcscat(Path, _T("\\"));\r
- _tcscat(Path, pUpdateList->File[i].DstPath);\r
- if(CreateDirectory(Path, NULL))\r
- b = TRUE;\r
+ if(p = _tcsrchr(LocalDir, _T('\\')))\r
+ *p = _T('\0');\r
}\r
- if(strlen(pUpdateList->File[i].SrcPath) > 0)\r
+ else\r
+ _tcscpy(LocalDir, _T("."));\r
+ for(i = 0; i < pUpdateList->FileCount; i++)\r
{\r
- if(ReadFileViaHTTP(pBuf, 16777216, &Length, HTTP_USER_AGENT, UPDATE_SERVER, pUpdateList->File[i].SrcPath))\r
+ b = FALSE;\r
+ if(pUpdateList->File[i].Flags & UPDATE_LIST_FILE_FLAG_DIRECTORY)\r
+ {\r
+ _tcscpy(Path, DownloadDir);\r
+ _tcscat(Path, pUpdateList->File[i].DstPath);\r
+ if(CreateDirectory(Path, NULL))\r
+ b = TRUE;\r
+ }\r
+ if(strlen(pUpdateList->File[i].SrcPath) > 0)\r
{\r
- GetHashSHA512(pBuf, Length, &Hash);\r
- if(memcmp(&Hash, &pUpdateList->File[i].SrcHash, 64) == 0)\r
+ _tcscpy(Path, LocalDir);\r
+ _tcscat(Path, pUpdateList->File[i].DstPath);\r
+ if(LoadMemoryFromFileWithTimestamp(Path, pBuf, UPDATE_MAX_FILE_SIZE, &Length, NULL))\r
{\r
- _tcscpy(Path, DownloadDir);\r
- _tcscat(Path, _T("\\"));\r
- _tcscat(Path, pUpdateList->File[i].DstPath);\r
- if(SaveMemoryToFileWithTimestamp(Path, pBuf, Length, &pUpdateList->File[i].Timestamp))\r
- b = TRUE;\r
+ if(GetHashSHA512(pBuf, Length, &Hash))\r
+ {\r
+ if(memcmp(&Hash, &pUpdateList->File[i].SrcHash, 64) == 0)\r
+ b = TRUE;\r
+ }\r
+ }\r
+ if(!b)\r
+ {\r
+ if(ReadFileViaHTTP(pBuf, UPDATE_MAX_FILE_SIZE, &Length, HTTP_USER_AGENT, UPDATE_SERVER, pUpdateList->File[i].SrcPath))\r
+ {\r
+ if(GetHashSHA512(pBuf, Length, &Hash))\r
+ {\r
+ if(memcmp(&Hash, &pUpdateList->File[i].SrcHash, 64) == 0)\r
+ {\r
+ _tcscpy(Path, DownloadDir);\r
+ _tcscat(Path, pUpdateList->File[i].DstPath);\r
+ if(SaveMemoryToFileWithTimestamp(Path, pBuf, Length, &pUpdateList->File[i].Timestamp))\r
+ b = TRUE;\r
+ }\r
+ }\r
+ }\r
}\r
}\r
+ if(!b)\r
+ {\r
+ bResult = FALSE;\r
+ break;\r
+ }\r
}\r
- if(!b)\r
- {\r
- bResult = FALSE;\r
- break;\r
- }\r
+ free(pBuf);\r
}\r
- free(pBuf);\r
}\r
}\r
return bResult;\r
_tcscat(Backup, _T("\\"));\r
_tcscat(Backup, BackupDirName);\r
DeleteDirectoryAndContents(Backup);\r
- if(CopyAllFilesInDirectory(DestinationDir, Backup))\r
+ if(CreateDirectory(Backup, NULL))\r
{\r
- _tcscpy(DestinationBackup, DestinationDir);\r
- _tcscat(DestinationBackup, _T("\\"));\r
- _tcscat(DestinationBackup, BackupDirName);\r
- if(CopyAllFilesInDirectory(Source, DestinationDir))\r
- {\r
- DeleteDirectoryAndContents(DestinationBackup);\r
- bResult = TRUE;\r
- }\r
- else\r
+ if(CopyAllFilesInDirectory(DestinationDir, Backup))\r
{\r
- DeleteDirectoryAndContents(DestinationBackup);\r
- CopyAllFilesInDirectory(Backup, DestinationDir);\r
+ _tcscpy(DestinationBackup, DestinationDir);\r
+ _tcscat(DestinationBackup, _T("\\"));\r
+ _tcscat(DestinationBackup, BackupDirName);\r
+ if(CopyAllFilesInDirectory(Source, DestinationDir))\r
+ {\r
+ DeleteDirectoryAndContents(DestinationBackup);\r
+ bResult = TRUE;\r
+ }\r
+ else\r
+ {\r
+ DeleteDirectoryAndContents(DestinationBackup);\r
+ CopyAllFilesInDirectory(Backup, DestinationDir);\r
+ }\r
}\r
}\r
}\r
memset(&Info, 0, sizeof(SHELLEXECUTEINFO));\r
Info.cbSize = sizeof(SHELLEXECUTEINFO);\r
Info.fMask = SEE_MASK_NOCLOSEPROCESS;\r
- Info.lpVerb = _T("runas");\r
+ if(IsUserAnAdmin())\r
+ Info.lpVerb = _T("open");\r
+ else\r
+ Info.lpVerb = _T("runas");\r
Info.lpFile = Path;\r
Info.lpParameters = NewCommandLine;\r
Info.nShow = SW_SHOW;\r