5 static IP_ADAPTER_INFO adapters
[256];
7 static BOOL (*wow64_disable
)(void **old
);
8 static BOOL (*wow64_enable
)(void *old
);
11 __declspec(dllimport
) BOOL
wow64_disable(void **old
);
12 __declspec(dllimport
) BOOL
wow64_enable(void *old
);
14 // add unique list item
15 static void adduniq(HWND list
, char *s
)
17 // dont add duplicate names and empty strings
19 if (SendMessage(list
, LB_FINDSTRINGEXACT
, 0, (LPARAM
)s
)==LB_ERR
)
20 SendMessage(list
, LB_ADDSTRING
, 0, (LPARAM
)s
);
23 // enumerate running processes and add to the list
24 static void enumproc(HWND list
)
27 char subname
[MAX_PATH
];
28 DWORD subsize
= sizeof(subname
);
30 lpe
.dwSize
= sizeof(lpe
);
31 for (i
=0;(t
=RegEnumValue(registry
, i
, subname
, &subsize
, NULL
, NULL
, NULL
, NULL
))==ERROR_SUCCESS
;i
++,subsize
=sizeof(subname
))
32 adduniq(list
, subname
);
33 HANDLE snap
= CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS
, 0);
34 BOOL entry
= Process32First(snap
, &lpe
);
36 if (PathMatchSpec(lpe
.szExeFile
, "*.exe"))
37 adduniq(list
, lpe
.szExeFile
);
38 lpe
.dwSize
= sizeof(lpe
);
39 entry
= Process32Next(snap
, &lpe
);
44 // add network interfacess to list
45 static void enumintf(HWND list
)
48 adduniq(list
, "(default route)");
49 for (ada
= adapters
; ada
; ada
= ada
->Next
)
50 adduniq(list
, ada
->Description
);
53 // react to user clicks in exe/intf list boxes
54 // il=1 if clicked on interface list
55 static void process_selections(HWND parent
, HWND exe
, HWND intf
, int il
)
57 static int sels
[16384];
58 static TCHAR buf
[512], buf2
[512];
59 IP_ADAPTER_INFO
*ada
, *curada
= NULL
;
62 // Clicked on exelist, go through selected exes
63 nsel
= SendMessage(exe
, LB_GETSELITEMS
, 16384, (LPARAM
)sels
);
64 if (!il
) for (i
= 0; i
< nsel
; i
++) {
65 DWORD len
= sizeof(buf2
);
66 SendMessage(exe
, LB_GETTEXT
, sels
[i
], (LPARAM
)buf
);
67 if (RegQueryValueEx(registry
, buf
,NULL
,NULL
, (LPBYTE
)buf2
, &len
)!=ERROR_SUCCESS
) {
68 // undefined key -> no adapter, default route, shortcut
73 // and check they have all interfaces in common
74 for (j
= 1, ada
= adapters
; ada
; ada
= ada
->Next
, j
++)
75 if (!strcmp(ada
->AdapterName
, buf2
)) {
76 // mismatch in selected group -> reset default route
77 if (curif
>= 0 && curif
!= j
) {
82 // otherwise keep as current interface
91 if (curif
< 0) curif
= 0;
92 SendMessage(intf
, LB_SETCURSEL
, curif
, 0);
94 // clicked interface list
95 curif
= SendMessage(intf
, LB_GETCURSEL
,0,0);
96 // resolve index to name
97 for (i
= curif
, ada
= adapters
; ada
&& i
--; ada
= ada
->Next
)
100 // in curif we have corresponding interface index, 0 if default
101 // in curada we have interface, null if default
102 // in sels[] we have exes this aplies to
103 for (i
= 0; i
< nsel
; i
++) {
104 SendMessage(exe
, LB_GETTEXT
, sels
[i
], (LPARAM
)buf
);
105 if (curif
> 0) { // assign new interface
106 RegSetValueExA(registry
, buf
, 0, REG_SZ
, (LPBYTE
)curada
->AdapterName
, strlen(curada
->AdapterName
)+1);
107 } else { // no interface, delete it
108 RegDeleteValue(registry
, buf
);
111 strcpy(buf
, "Default interface");
112 strcpy(buf2
, "Default source ip");
113 if (curif
> 0 && curada
) {
114 BYTE
*mac
= curada
->Address
;
115 char *pip
= curada
->IpAddressList
.IpAddress
.String
;
116 wnsprintf(buf
, sizeof(buf
), "%02x-%02x-%02x-%02x-%02x-%02x",
117 mac
[0], mac
[1], mac
[2], mac
[3], mac
[4], mac
[5]);
120 SendMessage(GetDlgItem(parent
, IDC_MAC
), WM_SETTEXT
, 0, (LPARAM
)buf
);
121 SendMessage(GetDlgItem(parent
, IDC_IP
), WM_SETTEXT
, 0, (LPARAM
)buf2
);
124 static int check_system_dlls(char *buf
, int len32
)
126 return !(GetFileAttributesA(buf
) == INVALID_FILE_ATTRIBUTES
|| GetFileAttributesA(buf
+len32
) == INVALID_FILE_ATTRIBUTES
);
129 // locate dlls in system directory
130 static int get_system_dlls(char *buf
)
135 if (!SHGetSpecialFolderPathA(NULL
, buf
, CSIDL_SYSTEMX86
, 0))
136 SHGetSpecialFolderPathA(NULL
, buf
, CSIDL_SYSTEM
, 0);
137 strcat(buf
, "\\bindip.dll");
138 len32
= strlen(buf
)+1;
139 SHGetSpecialFolderPathA(NULL
, buf
+ len32
, CSIDL_SYSTEM
, 0);
140 strcat(buf
+ len32
, "\\bindip.dll");
145 // locate dlls in all places
146 static int locate_dlls(char *buf
, int sys
)
153 len32
= get_system_dlls(buf
);
154 if (check_system_dlls(buf
, len32
))
157 for (i
= 0; i
< 3; i
++) {
160 ExpandEnvironmentStringsA("%PROGRAMFILES(X86)%\\BindIP", tbuf
, sizeof(tbuf
));
163 ExpandEnvironmentStringsA("%PROGRAMFILES%\\BindIP", tbuf
, sizeof(tbuf
));
166 GetModuleFileNameA(NULL
, tbuf
, sizeof(tbuf
));
167 PathRemoveFileSpecA(tbuf
);
170 len32
= wnsprintf(buf
, 2048, "%s\\bindip.dll", tbuf
)+1;
171 wnsprintf(buf
+ len32
, 2048, "%s\\64\\bindip.dll", tbuf
);
172 if (GetFileAttributesA(buf
) != INVALID_FILE_ATTRIBUTES
|| GetFileAttributesA(buf
+len32
) != INVALID_FILE_ATTRIBUTES
)
180 // configure global filter winsock
181 static int dll_config(HWND dlg
, int enable
)
184 char buf
[MAX_PATH
*2], buf2
[MAX_PATH
*2];
185 static char const orig
[] = "%SystemRoot%\\System32\\wshtcpip.dll";
186 DWORD buf2len
, buflen
= sizeof buf
;
189 if ((e
=RegOpenKeyExA(HKEY_LOCAL_MACHINE
, "SYSTEM\\CurrentControlSet\\services\\Tcpip\\Parameters\\Winsock", 0, KEY_ALL_ACCESS
, ®
))) {
191 Button_Enable(dlg
, 0);
196 if (RegQueryValueExA(reg
, "HelperDllName", 0, NULL
, (BYTE
*)buf
, &buflen
)) {
200 if (!strcmp(buf
+buflen
-11, "bindip.dll")) {
205 // request to disable
207 if (RegSetValueExA(reg
, "HelperDllName", 0, REG_EXPAND_SZ
, (BYTE
*)orig
, buflen
)) {
208 enable
= 1; // Failed to disable..
209 } else { // Disabled, delete dlls too
210 buflen
= get_system_dlls(buf
);
212 DeleteFile(buf
+buflen
);
214 } else if (enable
== 1) {
217 buflen
= get_system_dlls(buf
);
218 if (!check_system_dlls(buf
, buflen
)) {
219 buf2len
= locate_dlls(buf2
, 0);
220 CopyFile(buf2
+buf2len
, buf
+buflen
, FALSE
);
221 CopyFile(buf2
, buf
, FALSE
);
222 // Re-check that the files are ok now
223 if (!check_system_dlls(buf
, buflen
))
226 enable
= !RegSetValueExA(reg
, "HelperDllName", 0, REG_EXPAND_SZ
, (BYTE
*)buf
+buflen
, strlen(buf
+buflen
)+1);
227 } else enable
= 0; // Otherwise disabled
234 // configure shell button registry
235 // -1 - just query status
236 static int shell_config(int enable
)
239 RegOpenKeyExA(HKEY_CURRENT_USER
, "Software\\Classes\\exefile\\shell", 0, KEY_ALL_ACCESS
, ®
);
241 if (RegQueryValue(reg
, "Open with BindIP", NULL
, NULL
)==ERROR_SUCCESS
)
245 } else if (enable
== 1) {
246 char myname
[MAX_PATH
];
248 GetModuleFileName(NULL
, myname
, sizeof(myname
));
249 RegCreateKeyExA(reg
, "Open with BindIP\\command", 0, NULL
, 0, KEY_ALL_ACCESS
, NULL
, ®2
, NULL
);
250 enable
= !RegSetValueExA(reg2
, NULL
, 0, REG_SZ
, (BYTE
*)pbuf
,wnsprintf(pbuf
, sizeof(pbuf
), "\"%s\" \"%%1\"", myname
)+1);
254 SHDeleteKeyA(reg
, "Open with BindIP");
261 static INT_PTR CALLBACK
dialog_wproc(HWND dlg
, UINT msg
, WPARAM w
, LPARAM l
)
263 HWND exe
= GetDlgItem(dlg
, IDC_EXELIST
);
264 HWND intf
= GetDlgItem(dlg
, IDC_INTLIST
);
265 HWND appinit
= GetDlgItem(dlg
, IDC_APPINIT
);
266 HWND shell
= GetDlgItem(dlg
, IDC_SHELL
);
272 Button_SetCheck(shell
, shell_config(-1));
273 Button_SetCheck(appinit
, dll_config(appinit
,-1));
275 SendMessage(exe
, LB_SETSEL
, TRUE
, 0);
276 process_selections(dlg
,exe
,intf
, 0);
281 case WM_COMMAND
: switch (LOWORD(w
)) {
291 if (HIWORD(w
) == LBN_SELCHANGE
)
292 process_selections(dlg
, exe
,intf
,il
);
295 char filebuf
[MAX_PATH
];
298 .lStructSize
= sizeof(OPENFILENAME
),
300 .lpstrFile
= filebuf
,
301 .nMaxFile
= sizeof(filebuf
),
302 .lpstrFilter
= "EXE\0*.exe\0COM\0*.com\0SCR\0*.scr\0",
304 if (GetOpenFileName(&ofn
)) {
305 PathStripPathA(filebuf
);
306 adduniq(exe
, filebuf
);
307 SendMessage(exe
, LB_SETSEL
, FALSE
, (LPARAM
)-1);
308 SendMessage(exe
, LB_SETSEL
, TRUE
, SendMessage(exe
, LB_FINDSTRINGEXACT
, 0, (LPARAM
)filebuf
));
310 process_selections(dlg
,exe
,intf
, 0);
315 Button_SetCheck(shell
, shell_config(Button_GetCheck(shell
)));
318 ShellExecute(NULL
, "open", "http://lua.cz/bindip/1", NULL
, NULL
, SW_SHOWNORMAL
);
321 Button_SetCheck(appinit
, dll_config(appinit
, Button_GetCheck(appinit
)));
329 __declspec(dllimport
) char *inject(HANDLE hp
, HANDLE ht
, char *dll32
, int len32
);
330 __declspec(dllimport
) void cpiw_init();
331 static void run_preloaded(WCHAR
*cmd
)
334 char dlls
[MAX_PATH
*2];
335 STARTUPINFOW si
= {0};
336 PROCESS_INFORMATION pi
= {0};
337 int len32
= locate_dlls(dlls
, 0);
340 // Triggers our patched CreateProcessInternal
342 SetEnvironmentVariable("BINDIP_CHAINHOOK", dlls
);
343 cpiw_init(); // Patch createprocess
347 // Pass console handles
348 si
.dwFlags
= STARTF_USESTDHANDLES
;
349 si
.hStdError
= GetStdHandle(STD_ERROR_HANDLE
);
350 si
.hStdInput
= GetStdHandle(STD_INPUT_HANDLE
);
351 si
.hStdOutput
= GetStdHandle(STD_OUTPUT_HANDLE
);
354 if (!CreateProcessW(NULL
, cmd
, NULL
, NULL
, TRUE
, 0, NULL
, NULL
, &si
, &pi
)) {
355 MessageBoxA(NULL
, serr(), "CreateProcess", MB_ICONERROR
|MB_OK
);
359 if (WaitForInputIdle(pi
.hProcess
, INFINITE
) == WAIT_FAILED
) {
360 // Console process, setup break handler
361 WaitForSingleObject(pi
.hProcess
, INFINITE
);
362 GetExitCodeProcess(pi
.hProcess
, &ecode
);
364 // GUI app, close console
368 CloseHandle(pi
.hThread
);
369 CloseHandle(pi
.hProcess
);
376 // Skip over exe name
377 WCHAR
*cmd
= GetCommandLineW();
378 int quot
= *cmd
++ == L
'"';
379 while (*cmd
&& (quot
|| (cmd
[0]>L
' ')))
382 while (*cmd
&& *cmd
<= L
' ')
385 // Request to launch specified program
386 //static WCHAR fake[MAX_PATH] = L"nc.exe -h";
391 ULONG len
= sizeof(adapters
);
395 RegCreateKeyEx(HKEY_CURRENT_USER
, "Software\\BindIP\\Mapping", 0, NULL
, 0, KEY_ALL_ACCESS
, NULL
, ®istry
, &disp
);
396 if (disp
== REG_CREATED_NEW_KEY
) {
397 // Run for the first time - enable shell, delete system dlls if possible
400 } else if (shell_config(-1)) // Shell enabled, re-enable again to update exe path in registry
402 GetAdaptersInfo(adapters
, &len
);
403 // And fire up dialog
404 DialogBox(NULL
, MAKEINTRESOURCE(IDD_FORMVIEW
), NULL
, dialog_wproc
);
405 RegCloseKey(registry
);