Fix some possible resource leaks
[TortoiseGit.git] / src / TortoisePlink / Windows / WINNOISE.C
blobce390dbc2856bdb2fa5d41006539cbb9f29fb933
1 /*\r
2  * Noise generation for PuTTY's cryptographic random number\r
3  * generator.\r
4  */\r
5 \r
6 #include <stdio.h>\r
7 \r
8 #include "putty.h"\r
9 #include "ssh.h"\r
10 #include "storage.h"\r
12 #include <wincrypt.h>\r
14 DECL_WINDOWS_FUNCTION(static, BOOL, CryptAcquireContextA,\r
15                       (HCRYPTPROV *, LPCTSTR, LPCTSTR, DWORD, DWORD));\r
16 DECL_WINDOWS_FUNCTION(static, BOOL, CryptGenRandom,\r
17                       (HCRYPTPROV, DWORD, BYTE *));\r
18 DECL_WINDOWS_FUNCTION(static, BOOL, CryptReleaseContext,\r
19                       (HCRYPTPROV, DWORD));\r
20 static HMODULE wincrypt_module = NULL;\r
22 /*\r
23  * This function is called once, at PuTTY startup.\r
24  */\r
26 void noise_get_heavy(void (*func) (void *, int))\r
27 {\r
28     HANDLE srch;\r
29     WIN32_FIND_DATA finddata;\r
30     DWORD pid;\r
31     HCRYPTPROV crypt_provider;\r
32     char winpath[MAX_PATH + 3];\r
34     GetWindowsDirectory(winpath, sizeof(winpath));\r
35     strcat(winpath, "\\*");\r
36     srch = FindFirstFile(winpath, &finddata);\r
37     if (srch != INVALID_HANDLE_VALUE) {\r
38         do {\r
39             func(&finddata, sizeof(finddata));\r
40         } while (FindNextFile(srch, &finddata));\r
41         FindClose(srch);\r
42     }\r
44     pid = GetCurrentProcessId();\r
45     func(&pid, sizeof(pid));\r
47     if (!wincrypt_module) {\r
48         wincrypt_module = load_system32_dll("advapi32.dll");\r
49         GET_WINDOWS_FUNCTION(wincrypt_module, CryptAcquireContextA);\r
50         GET_WINDOWS_FUNCTION(wincrypt_module, CryptGenRandom);\r
51         GET_WINDOWS_FUNCTION(wincrypt_module, CryptReleaseContext);\r
52     }\r
54     if (wincrypt_module && p_CryptAcquireContextA &&\r
55         p_CryptGenRandom && p_CryptReleaseContext &&\r
56         p_CryptAcquireContextA(&crypt_provider, NULL, NULL, PROV_RSA_FULL,\r
57                                CRYPT_VERIFYCONTEXT)) {\r
58         BYTE buf[32];\r
59         if (p_CryptGenRandom(crypt_provider, 32, buf)) {\r
60             func(buf, sizeof(buf));\r
61         }\r
62         p_CryptReleaseContext(crypt_provider, 0);\r
63     }\r
65     read_random_seed(func);\r
66     /* Update the seed immediately, in case another instance uses it. */\r
67     random_save_seed();\r
68 }\r
70 void random_save_seed(void)\r
71 {\r
72     int len;\r
73     void *data;\r
75     if (random_active) {\r
76         random_get_savedata(&data, &len);\r
77         write_random_seed(data, len);\r
78         sfree(data);\r
79     }\r
80 }\r
82 /*\r
83  * This function is called every time the random pool needs\r
84  * stirring, and will acquire the system time in all available\r
85  * forms.\r
86  */\r
87 void noise_get_light(void (*func) (void *, int))\r
88 {\r
89     SYSTEMTIME systime;\r
90     DWORD adjust[2];\r
91     BOOL rubbish;\r
93     GetSystemTime(&systime);\r
94     func(&systime, sizeof(systime));\r
96     GetSystemTimeAdjustment(&adjust[0], &adjust[1], &rubbish);\r
97     func(&adjust, sizeof(adjust));\r
98 }\r
100 /*\r
101  * This function is called on a timer, and it will monitor\r
102  * frequently changing quantities such as the state of physical and\r
103  * virtual memory, the state of the process's message queue, which\r
104  * window is in the foreground, which owns the clipboard, etc.\r
105  */\r
106 void noise_regular(void)\r
108     HWND w;\r
109     DWORD z;\r
110     POINT pt;\r
111     MEMORYSTATUS memstat;\r
112     FILETIME times[4];\r
114     w = GetForegroundWindow();\r
115     random_add_noise(&w, sizeof(w));\r
116     w = GetCapture();\r
117     random_add_noise(&w, sizeof(w));\r
118     w = GetClipboardOwner();\r
119     random_add_noise(&w, sizeof(w));\r
120     z = GetQueueStatus(QS_ALLEVENTS);\r
121     random_add_noise(&z, sizeof(z));\r
123     GetCursorPos(&pt);\r
124     random_add_noise(&pt, sizeof(pt));\r
126     GlobalMemoryStatus(&memstat);\r
127     random_add_noise(&memstat, sizeof(memstat));\r
129     GetThreadTimes(GetCurrentThread(), times, times + 1, times + 2,\r
130                    times + 3);\r
131     random_add_noise(&times, sizeof(times));\r
132     GetProcessTimes(GetCurrentProcess(), times, times + 1, times + 2,\r
133                     times + 3);\r
134     random_add_noise(&times, sizeof(times));\r
137 /*\r
138  * This function is called on every keypress or mouse move, and\r
139  * will add the current Windows time and performance monitor\r
140  * counter to the noise pool. It gets the scan code or mouse\r
141  * position passed in.\r
142  */\r
143 void noise_ultralight(unsigned long data)\r
145     DWORD wintime;\r
146     LARGE_INTEGER perftime;\r
148     random_add_noise(&data, sizeof(DWORD));\r
150     wintime = GetTickCount();\r
151     random_add_noise(&wintime, sizeof(DWORD));\r
153     if (QueryPerformanceCounter(&perftime))\r
154         random_add_noise(&perftime, sizeof(perftime));\r