OSDN Git Service

Fix bugs of 64bit binaries.
[ffftp/ffftp.git] / updater.c
1 // updater.c\r
2 // Copyright (C) 2014 Suguru Kawamoto\r
3 // ソフトウェア自動更新\r
4 \r
5 #include <tchar.h>\r
6 #include <ws2tcpip.h>\r
7 #include <windows.h>\r
8 #include <mmsystem.h>\r
9 typedef SOCKADDR_STORAGE_XP SOCKADDR_STORAGE;\r
10 typedef SOCKADDR_STORAGE *PSOCKADDR_STORAGE, FAR *LPSOCKADDR_STORAGE;\r
11 #include <winhttp.h>\r
12 \r
13 #include "updater.h"\r
14 #include "socketwrapper.h"\r
15 #include "protectprocess.h"\r
16 #include "mbswrapper.h"\r
17 \r
18 typedef struct\r
19 {\r
20         BYTE Signature[64];\r
21         BYTE ListHash[64];\r
22 } UPDATE_HASH;\r
23 \r
24 BOOL DownloadFileViaHTTP(void* pOut, DWORD Length, DWORD* pLength, LPCWSTR UserAgent, LPCWSTR ServerName, LPCWSTR ObjectName)\r
25 {\r
26         BOOL bResult;\r
27         HINTERNET hSession;\r
28         HINTERNET hConnect;\r
29         HINTERNET hRequest;\r
30         bResult = FALSE;\r
31         if(hSession = WinHttpOpen(UserAgent, WINHTTP_ACCESS_TYPE_NO_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0))\r
32         {\r
33                 if(hConnect = WinHttpConnect(hSession, ServerName, INTERNET_DEFAULT_HTTP_PORT, 0))\r
34                 {\r
35                         if(hRequest = WinHttpOpenRequest(hConnect, L"GET", ObjectName, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0))\r
36                         {\r
37                                 if(WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0))\r
38                                 {\r
39                                         if(WinHttpReceiveResponse(hRequest, NULL))\r
40                                         {\r
41                                                 if(WinHttpQueryDataAvailable(hRequest, pLength))\r
42                                                 {\r
43                                                         if(*pLength <= Length)\r
44                                                         {\r
45                                                                 if(WinHttpReadData(hRequest, pOut, Length, pLength))\r
46                                                                         bResult = TRUE;\r
47                                                         }\r
48                                                 }\r
49                                         }\r
50                                 }\r
51                                 WinHttpCloseHandle(hRequest);\r
52                         }\r
53                         WinHttpCloseHandle(hConnect);\r
54                 }\r
55                 WinHttpCloseHandle(hSession);\r
56         }\r
57         return bResult;\r
58 }\r
59 \r
60 // FFFTPの更新情報を確認\r
61 BOOL CheckForUpdates(BOOL bDownload, LPCTSTR DownloadDir)\r
62 {\r
63         BOOL bResult;\r
64         DWORD Length;\r
65         BYTE Buf1[4096];\r
66         BYTE Buf2[1024];\r
67         UPDATE_HASH UpdateHash;\r
68         BYTE Hash[64];\r
69         bResult = FALSE;\r
70         if(DownloadFileViaHTTP(&Buf1, sizeof(Buf1), &Length, HTTP_USER_AGENT, UPDATE_SERVER, UPDATE_HASH_PATH))\r
71         {\r
72                 if(DecryptSignature(UPDATE_RSA_PUBLIC_KEY, &Buf1, Length, &Buf2, sizeof(Buf2), &Length))\r
73                 {\r
74                         if(Length == sizeof(UPDATE_HASH))\r
75                         {\r
76                                 memcpy(&UpdateHash, &Buf2, sizeof(UPDATE_HASH));\r
77                                 if(memcmp(&UpdateHash.Signature, UPDATE_SIGNATURE, 64) == 0)\r
78                                 {\r
79                                         if(DownloadFileViaHTTP(&Buf1, sizeof(Buf1), &Length, HTTP_USER_AGENT, UPDATE_SERVER, UPDATE_LIST_PATH))\r
80                                         {\r
81                                                 GetHashSHA512(&Buf1, Length, &Hash);\r
82                                                 if(memcmp(&Hash, &UpdateHash.ListHash, 64) == 0)\r
83                                                 {\r
84                                                         // TODO: 更新情報を解析\r
85                                                         bResult = TRUE;\r
86                                                         if(bDownload)\r
87                                                                 bResult = PrepareUpdates(&Buf1, Length, DownloadDir);\r
88                                                 }\r
89                                         }\r
90                                 }\r
91                         }\r
92                 }\r
93         }\r
94         return bResult;\r
95 }\r
96 \r
97 // 更新するファイルをダウンロード\r
98 BOOL PrepareUpdates(void* pList, DWORD ListLength, LPCTSTR DownloadDir)\r
99 {\r
100         BOOL bResult;\r
101         bResult = FALSE;\r
102         // TODO: 更新情報を解析\r
103         // TODO: 更新するファイルをダウンロード\r
104         return bResult;\r
105 }\r
106 \r
107 // FFFTPを更新\r
108 BOOL ApplyUpdates(LPCTSTR DestinationDir)\r
109 {\r
110         BOOL bResult;\r
111         bResult = FALSE;\r
112         // TODO:\r
113         return bResult;\r
114 }\r
115 \r
116 // 更新用のプロセスを起動\r
117 BOOL StartUpdateProcess(LPCTSTR Path, LPCTSTR CommandLine)\r
118 {\r
119         BOOL bResult;\r
120         bResult = FALSE;\r
121         if(ShellExecute(NULL, "open", Path, CommandLine, NULL, SW_SHOW) > (HINSTANCE)32)\r
122                 bResult = TRUE;\r
123         return bResult;\r
124 }\r
125 \r
126 // 更新用のプロセスを管理者権限で起動\r
127 // Windows XP以前など起動できない場合は現在のプロセスで処理を続行\r
128 BOOL StartUpdateProcessAsAdministrator(LPCTSTR CommandLine, LPCTSTR Keyword)\r
129 {\r
130         BOOL bResult;\r
131         TCHAR* NewCommandLine;\r
132         TCHAR Path[MAX_PATH];\r
133         SHELLEXECUTEINFO Info;\r
134         bResult = FALSE;\r
135         if(_tcslen(CommandLine) < _tcslen(Keyword) || _tcscmp(CommandLine + _tcslen(CommandLine) - _tcslen(Keyword), Keyword) != 0)\r
136         {\r
137                 if(NewCommandLine = (TCHAR*)malloc(sizeof(TCHAR) * (_tcslen(CommandLine) + _tcslen(Keyword) + 1)))\r
138                 {\r
139                         _tcscpy(NewCommandLine, CommandLine);\r
140                         _tcscat(NewCommandLine, Keyword);\r
141                         GetModuleFileName(NULL, Path, MAX_PATH);\r
142                         memset(&Info, 0, sizeof(SHELLEXECUTEINFO));\r
143                         Info.cbSize = sizeof(SHELLEXECUTEINFO);\r
144                         Info.fMask = SEE_MASK_NOCLOSEPROCESS;\r
145                         Info.lpVerb = "runas";\r
146                         Info.lpFile = Path;\r
147                         Info.lpParameters = NewCommandLine;\r
148                         Info.nShow = SW_SHOW;\r
149                         if(ShellExecuteEx(&Info))\r
150                         {\r
151                                 WaitForSingleObject(Info.hProcess, INFINITE);\r
152                                 CloseHandle(Info.hProcess);\r
153                                 bResult = TRUE;\r
154                         }\r
155                         free(NewCommandLine);\r
156                 }\r
157         }\r
158         return bResult;\r
159 }\r
160 \r