fd371f42d19ab5606fe670c06267d52f9cdb44e4
[reactos.git] / reactos / lib / packet / Packet32.c
1 /*
2 * Copyright (c) 1999, 2000
3 * Politecnico di Torino. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that: (1) source code distributions
7 * retain the above copyright notice and this paragraph in its entirety, (2)
8 * distributions including binary code include the above copyright notice and
9 * this paragraph in its entirety in the documentation or other materials
10 * provided with the distribution, and (3) all advertising materials mentioning
11 * features or use of this software display the following acknowledgement:
12 * ``This product includes software developed by the Politecnico
13 * di Torino, and its contributors.'' Neither the name of
14 * the University nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior
16 * written permission.
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 */
21
22 #define UNICODE 1
23
24 #include <packet32.h>
25 #include <windows.h>
26 #include <windowsx.h>
27 #include <ntddndis.h>
28
29
30 /// Title of error windows
31 TCHAR szWindowTitle[] = TEXT("PACKET.DLL");
32
33 #if _DBG
34 #define ODS(_x) OutputDebugString(TEXT(_x))
35 #define ODSEx(_x, _y)
36 #else
37 #ifdef _DEBUG_TO_FILE
38 #include <stdio.h>
39 // Macro to print a debug string. The behavior differs depending on the debug level
40 #define ODS(_x) { \
41 FILE *f; \
42 f = fopen("winpcap_debug.txt", "a"); \
43 fprintf(f, "%s", _x); \
44 fclose(f); \
45 }
46 // Macro to print debug data with the printf convention. The behavior differs depending on */
47 #define ODSEx(_x, _y) { \
48 FILE *f; \
49 f = fopen("winpcap_debug.txt", "a"); \
50 fprintf(f, _x, _y); \
51 fclose(f); \
52 }
53
54 LONG PacketDumpRegistryKey(PCHAR KeyName, PCHAR FileName);
55 #else
56 #define ODS(_x)
57 #define ODSEx(_x, _y)
58 #endif
59 #endif
60
61 //service handles
62 SC_HANDLE scmHandle = NULL;
63 SC_HANDLE srvHandle = NULL;
64 LPCTSTR NPFServiceName = TEXT("NPF");
65 LPCTSTR NPFServiceDesc = TEXT("Netgroup Packet Filter");
66 LPCTSTR NPFDriverName = TEXT("\\npf.sys");
67 LPCTSTR NPFRegistryLocation = TEXT("SYSTEM\\CurrentControlSet\\Services\\NPF");
68
69
70 //---------------------------------------------------------------------------
71
72 BOOL APIENTRY DllMain (HANDLE DllHandle,DWORD Reason,LPVOID lpReserved)
73 {
74 BOOLEAN Status=TRUE;
75
76 switch ( Reason )
77 {
78 case DLL_PROCESS_ATTACH:
79
80 ODS("\n************Packet32: DllMain************\n");
81
82 #ifdef _DEBUG_TO_FILE
83 // dump a bunch of registry keys useful for debug to file
84 PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}",
85 "adapters.reg");
86 PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip",
87 "tcpip.reg");
88 PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\NPF",
89 "npf.reg");
90 PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services",
91 "services.reg");
92 #endif
93 break;
94
95 case DLL_PROCESS_DETACH:
96 break;
97
98 default:
99 break;
100 }
101
102 return Status;
103 }
104
105 //---------------------------------------------------------------------------
106
107 WCHAR* SChar2WChar(char* string)
108 {
109 WCHAR* TmpStr;
110 TmpStr=(WCHAR*) malloc ((strlen(string)+2)*sizeof(WCHAR));
111
112 MultiByteToWideChar(CP_ACP, 0, string, -1, TmpStr, (strlen(string)+2));
113
114 return TmpStr;
115 }
116
117 //---------------------------------------------------------------------------
118
119 BOOLEAN PacketSetMaxLookaheadsize (LPADAPTER AdapterObject)
120 {
121 BOOLEAN Status;
122 ULONG IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1);
123 PPACKET_OID_DATA OidData;
124
125 OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength);
126 if (OidData == NULL) {
127 ODS("PacketSetMaxLookaheadsize failed\n");
128 return FALSE;
129 }
130
131 //set the size of the lookahead buffer to the maximum available by the the NIC driver
132 OidData->Oid=OID_GEN_MAXIMUM_LOOKAHEAD;
133 OidData->Length=sizeof(ULONG);
134 Status=PacketRequest(AdapterObject,FALSE,OidData);
135 OidData->Oid=OID_GEN_CURRENT_LOOKAHEAD;
136 Status=PacketRequest(AdapterObject,TRUE,OidData);
137 GlobalFreePtr(OidData);
138 return Status;
139 }
140
141 //---------------------------------------------------------------------------
142
143 BOOLEAN PacketSetReadEvt(LPADAPTER AdapterObject)
144 {
145 DWORD BytesReturned;
146 TCHAR EventName[39];
147
148 // this tells the terminal service to retrieve the event from the global namespace
149 wcsncpy(EventName,L"Global\\",sizeof(L"Global\\"));
150
151 // retrieve the name of the shared event from the driver
152 if(DeviceIoControl(AdapterObject->hFile,pBIOCEVNAME,NULL,0,EventName+7,13*sizeof(TCHAR),&BytesReturned,NULL)==FALSE) return FALSE;
153
154 EventName[20]=0; // terminate the string
155
156 // open the shared event
157 AdapterObject->ReadEvent=CreateEvent(NULL,
158 TRUE,
159 FALSE,
160 EventName);
161
162 // in NT4 "Global\" is not automatically ignored: try to use simply the event name
163 if(GetLastError()!=ERROR_ALREADY_EXISTS){
164 if(AdapterObject->ReadEvent != NULL)
165 CloseHandle(AdapterObject->ReadEvent);
166
167 // open the shared event
168 AdapterObject->ReadEvent=CreateEvent(NULL,
169 TRUE,
170 FALSE,
171 EventName+7);
172 }
173
174 if(AdapterObject->ReadEvent==NULL || GetLastError()!=ERROR_ALREADY_EXISTS){
175 ODS("PacketSetReadEvt: error retrieving the event from the kernel\n");
176 return FALSE;
177 }
178
179 AdapterObject->ReadTimeOut=0;
180
181 return TRUE;
182
183 }
184
185 //---------------------------------------------------------------------------
186
187 BOOL PacketInstallDriver(SC_HANDLE ascmHandle,SC_HANDLE *srvHandle,TCHAR *driverPath)
188 {
189 BOOL result = FALSE;
190 ULONG err;
191
192 ODS("installdriver\n")
193
194 if (GetFileAttributes(driverPath) != 0xffffffff) {
195 *srvHandle = CreateService(ascmHandle,
196 NPFServiceName,
197 NPFServiceDesc,
198 SERVICE_ALL_ACCESS,
199 SERVICE_KERNEL_DRIVER,
200 SERVICE_DEMAND_START,
201 SERVICE_ERROR_NORMAL,
202 driverPath,
203 NULL, NULL, NULL, NULL, NULL);
204 if (*srvHandle == NULL) {
205 if (GetLastError() == ERROR_SERVICE_EXISTS) {
206 //npf.sys already existed
207 result = TRUE;
208 }
209 }
210 else {
211 //Created service for npf.sys
212 result = TRUE;
213 }
214 }
215 if (result == TRUE)
216 if (*srvHandle != NULL)
217 CloseServiceHandle(*srvHandle);
218
219 if(result == FALSE){
220 err = GetLastError();
221 if(err != 2)
222 ODSEx("PacketInstallDriver failed, Error=%d\n",err);
223 }
224 return result;
225
226 }
227
228 //---------------------------------------------------------------------------
229
230 ULONG inet_addrU(const WCHAR *cp)
231 {
232 ULONG val, part;
233 WCHAR c;
234 int i;
235
236 val = 0;
237 for (i = 0; i < 4; i++) {
238 part = 0;
239 while ((c = *cp++) != '\0' && c != '.') {
240 if (c < '0' || c > '9')
241 return -1;
242 part = part*10 + (c - '0');
243 }
244 if (part > 255)
245 return -1;
246 val = val | (part << i*8);
247 if (i == 3) {
248 if (c != '\0')
249 return -1; // extra gunk at end of string
250 } else {
251 if (c == '\0')
252 return -1; // string ends early
253 }
254 }
255 return val;
256 }
257
258 //---------------------------------------------------------------------------
259
260 #ifdef _DEBUG_TO_FILE
261
262 LONG PacketDumpRegistryKey(PCHAR KeyName, PCHAR FileName)
263 {
264 CHAR Command[256];
265
266 strcpy(Command, "regedit /e ");
267 strcat(Command, FileName);
268 strcat(Command, " ");
269 strcat(Command, KeyName);
270
271 /// Let regedit do the dirt work for us
272 system(Command);
273
274 return TRUE;
275 }
276 #endif
277
278 //---------------------------------------------------------------------------
279 // PUBLIC API
280 //---------------------------------------------------------------------------
281
282 /// Current packet.dll Version. It can be retrieved directly or through the PacketGetVersion() function.
283 char PacketLibraryVersion[] = "2.3";
284
285 //---------------------------------------------------------------------------
286
287 PCHAR PacketGetVersion(){
288 return PacketLibraryVersion;
289 }
290
291 //---------------------------------------------------------------------------
292
293 BOOLEAN PacketGetNetType (LPADAPTER AdapterObject,NetType *type)
294 {
295 BOOLEAN Status;
296 ULONG IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1);
297 PPACKET_OID_DATA OidData;
298
299 OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength);
300 if (OidData == NULL) {
301 ODS("PacketGetNetType failed\n");
302 return FALSE;
303 }
304 //get the link-layer type
305 OidData->Oid = OID_GEN_MEDIA_IN_USE;
306 OidData->Length = sizeof (ULONG);
307 Status = PacketRequest(AdapterObject,FALSE,OidData);
308 type->LinkType=*((UINT*)OidData->Data);
309
310 //get the link-layer speed
311 OidData->Oid = OID_GEN_LINK_SPEED;
312 OidData->Length = sizeof (ULONG);
313 Status = PacketRequest(AdapterObject,FALSE,OidData);
314 type->LinkSpeed=*((UINT*)OidData->Data)*100;
315 GlobalFreePtr (OidData);
316
317 ODSEx("Media:%d ",type->LinkType);
318 ODSEx("Speed=%d\n",type->LinkSpeed);
319
320 return Status;
321 }
322
323 //---------------------------------------------------------------------------
324
325 BOOL PacketStopDriver()
326 {
327 SC_HANDLE scmHandle;
328 SC_HANDLE schService;
329 BOOL ret;
330 SERVICE_STATUS serviceStatus;
331
332 scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
333
334 if(scmHandle != NULL){
335
336 schService = OpenService (scmHandle,
337 NPFServiceName,
338 SERVICE_ALL_ACCESS
339 );
340
341 if (schService != NULL)
342 {
343
344 ret = ControlService (schService,
345 SERVICE_CONTROL_STOP,
346 &serviceStatus
347 );
348 if (!ret)
349 {
350 }
351
352 CloseServiceHandle (schService);
353
354 CloseServiceHandle(scmHandle);
355
356 return ret;
357 }
358 }
359
360 return FALSE;
361
362 }
363
364 //---------------------------------------------------------------------------
365
366 LPADAPTER PacketOpenAdapter(LPTSTR AdapterName)
367 {
368 LPADAPTER lpAdapter;
369 BOOLEAN Result;
370 char *AdapterNameA;
371 WCHAR *AdapterNameU;
372 DWORD error;
373 SC_HANDLE svcHandle = NULL;
374 TCHAR driverPath[512];
375 TCHAR WinPath[256];
376 LONG KeyRes;
377 HKEY PathKey;
378 SERVICE_STATUS SStat;
379 BOOLEAN QuerySStat;
380
381 ODSEx("PacketOpenAdapter: trying to open the adapter=%S\n",AdapterName)
382
383 scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
384
385 if(scmHandle == NULL){
386 error = GetLastError();
387 ODSEx("OpenSCManager failed! Error=%d\n", error);
388 }
389 else{
390 *driverPath = 0;
391 GetCurrentDirectory(512, driverPath);
392 wsprintf(driverPath + wcslen(driverPath),
393 NPFDriverName);
394
395 // check if the NPF registry key is already present
396 // this means that the driver is already installed and that we don't need to call PacketInstallDriver
397 KeyRes=RegOpenKeyEx(HKEY_LOCAL_MACHINE,
398 NPFRegistryLocation,
399 0,
400 KEY_READ,
401 &PathKey);
402
403 if(KeyRes != ERROR_SUCCESS){
404 Result = PacketInstallDriver(scmHandle,&svcHandle,driverPath);
405 }
406 else{
407 Result = TRUE;
408 RegCloseKey(PathKey);
409 }
410
411 if (Result) {
412
413 srvHandle = OpenService(scmHandle, NPFServiceName, SERVICE_START | SERVICE_QUERY_STATUS );
414 if (srvHandle != NULL){
415
416 QuerySStat = QueryServiceStatus(srvHandle, &SStat);
417 ODSEx("The status of the driver is:%d\n",SStat.dwCurrentState);
418
419 if(!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING){
420 ODS("Calling startservice\n");
421 if (StartService(srvHandle, 0, NULL)==0){
422 error = GetLastError();
423 if(error!=ERROR_SERVICE_ALREADY_RUNNING && error!=ERROR_ALREADY_EXISTS){
424 SetLastError(error);
425 if (scmHandle != NULL) CloseServiceHandle(scmHandle);
426 error = GetLastError();
427 ODSEx("PacketOpenAdapter: StartService failed, Error=%d\n",error);
428 return NULL;
429 }
430 }
431 }
432 }
433 else{
434 error = GetLastError();
435 ODSEx("OpenService failed! Error=%d", error);
436 }
437 }
438 else{
439 if( GetSystemDirectory(WinPath, sizeof(WinPath)/sizeof(TCHAR)) == 0) return FALSE;
440 wsprintf(driverPath,
441 TEXT("%s\\drivers%s"),
442 WinPath,NPFDriverName);
443
444 if(KeyRes != ERROR_SUCCESS)
445 Result = PacketInstallDriver(scmHandle,&svcHandle,driverPath);
446 else
447 Result = TRUE;
448
449 if (Result) {
450
451 srvHandle = OpenService(scmHandle,NPFServiceName,SERVICE_START);
452 if (srvHandle != NULL){
453
454 QuerySStat = QueryServiceStatus(srvHandle, &SStat);
455 ODSEx("The status of the driver is:%d\n",SStat.dwCurrentState);
456
457 if(!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING){
458
459 ODS("Calling startservice\n");
460
461 if (StartService(srvHandle, 0, NULL)==0){
462 error = GetLastError();
463 if(error!=ERROR_SERVICE_ALREADY_RUNNING && error!=ERROR_ALREADY_EXISTS){
464 SetLastError(error);
465 if (scmHandle != NULL) CloseServiceHandle(scmHandle);
466 ODSEx("PacketOpenAdapter: StartService failed, Error=%d\n",error);
467 return NULL;
468 }
469 }
470 }
471 }
472 else{
473 error = GetLastError();
474 ODSEx("OpenService failed! Error=%d", error);
475 }
476 }
477 }
478 }
479
480 if (scmHandle != NULL) CloseServiceHandle(scmHandle);
481
482 AdapterNameA=(char*)AdapterName;
483 if(AdapterNameA[1]!=0){ //ASCII
484 AdapterNameU=SChar2WChar(AdapterNameA);
485 AdapterName=AdapterNameU;
486 } else { //Unicode
487 AdapterNameU=NULL;
488 }
489
490 lpAdapter=(LPADAPTER)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,sizeof(ADAPTER));
491 if (lpAdapter==NULL)
492 {
493 ODS("PacketOpenAdapter: GlobalAlloc Failed\n");
494 error=GetLastError();
495 if (AdapterNameU != NULL) free(AdapterNameU);
496 //set the error to the one on which we failed
497 SetLastError(error);
498 ODS("PacketOpenAdapter: Failed to allocate the adapter structure\n");
499 return NULL;
500 }
501 lpAdapter->NumWrites=1;
502
503 wsprintf(lpAdapter->SymbolicLink,TEXT("\\\\.\\%s%s"),DOSNAMEPREFIX,&AdapterName[8]);
504
505 //try if it is possible to open the adapter immediately
506 lpAdapter->hFile=CreateFile(lpAdapter->SymbolicLink,GENERIC_WRITE | GENERIC_READ,
507 0,NULL,OPEN_EXISTING,0,0);
508
509 if (lpAdapter->hFile != INVALID_HANDLE_VALUE) {
510
511 if(PacketSetReadEvt(lpAdapter)==FALSE){
512 error=GetLastError();
513 ODS("PacketOpenAdapter: Unable to open the read event\n");
514 if (AdapterNameU != NULL)
515 free(AdapterNameU);
516 GlobalFreePtr(lpAdapter);
517 //set the error to the one on which we failed
518 SetLastError(error);
519 ODSEx("PacketOpenAdapter: PacketSetReadEvt failed, Error=%d\n",error);
520 return NULL;
521 }
522
523 PacketSetMaxLookaheadsize(lpAdapter);
524 if (AdapterNameU != NULL)
525 free(AdapterNameU);
526 return lpAdapter;
527 }
528 //this is probably the first request on the packet driver.
529 //We must create the dos device and set the access rights on it
530 else{
531 Result=DefineDosDevice(DDD_RAW_TARGET_PATH,&lpAdapter->SymbolicLink[4],AdapterName);
532 if (Result)
533 {
534
535 lpAdapter->hFile=CreateFile(lpAdapter->SymbolicLink,GENERIC_WRITE | GENERIC_READ,
536 0,NULL,OPEN_EXISTING,0,0);
537 if (lpAdapter->hFile != INVALID_HANDLE_VALUE)
538 {
539
540 if(PacketSetReadEvt(lpAdapter)==FALSE){
541 error=GetLastError();
542 ODS("PacketOpenAdapter: Unable to open the read event\n");
543 if (AdapterNameU != NULL)
544 free(AdapterNameU);
545 GlobalFreePtr(lpAdapter);
546 //set the error to the one on which we failed
547 SetLastError(error);
548 ODSEx("PacketOpenAdapter: PacketSetReadEvt failed, Error=1,%d\n",error);
549 return NULL;
550 }
551
552 PacketSetMaxLookaheadsize(lpAdapter);
553 if (AdapterNameU != NULL)
554 free(AdapterNameU);
555 return lpAdapter;
556 }
557 }
558 }
559
560 error=GetLastError();
561 if (AdapterNameU != NULL)
562 free(AdapterNameU);
563 GlobalFreePtr(lpAdapter);
564 //set the error to the one on which we failed
565 SetLastError(error);
566 ODSEx("PacketOpenAdapter: CreateFile failed, Error=2,%d\n",error);
567 return NULL;
568
569 }
570
571 //---------------------------------------------------------------------------
572
573 VOID PacketCloseAdapter(LPADAPTER lpAdapter)
574 {
575 CloseHandle(lpAdapter->hFile);
576 SetEvent(lpAdapter->ReadEvent);
577 CloseHandle(lpAdapter->ReadEvent);
578 GlobalFreePtr(lpAdapter);
579 }
580
581 //---------------------------------------------------------------------------
582
583 LPPACKET PacketAllocatePacket(void)
584 {
585
586 LPPACKET lpPacket;
587 lpPacket=(LPPACKET)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,sizeof(PACKET));
588 if (lpPacket==NULL)
589 {
590 ODS("PacketAllocatePacket: GlobalAlloc Failed\n");
591 return NULL;
592 }
593 return lpPacket;
594 }
595
596 //---------------------------------------------------------------------------
597
598 VOID PacketFreePacket(LPPACKET lpPacket)
599 {
600 GlobalFreePtr(lpPacket);
601 }
602
603 //---------------------------------------------------------------------------
604
605 VOID PacketInitPacket(LPPACKET lpPacket,PVOID Buffer,UINT Length)
606 {
607 lpPacket->Buffer = Buffer;
608 lpPacket->Length = Length;
609 lpPacket->ulBytesReceived = 0;
610 lpPacket->bIoComplete = FALSE;
611 }
612
613 //---------------------------------------------------------------------------
614
615 BOOLEAN PacketReceivePacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync)
616 {
617 BOOLEAN res;
618 if ((int)AdapterObject->ReadTimeOut != -1)
619 WaitForSingleObject(AdapterObject->ReadEvent, (AdapterObject->ReadTimeOut==0)?INFINITE:AdapterObject->ReadTimeOut);
620 res = ReadFile(AdapterObject->hFile, lpPacket->Buffer, lpPacket->Length, &lpPacket->ulBytesReceived,NULL);
621 return res;
622 }
623 /*
624 ReadFile(
625 HANDLE hFile,
626 LPVOID lpBuffer,
627 DWORD nNumberOfBytesToRead,
628 LPDWORD lpNumberOfBytesRead,
629 LPOVERLAPPED lpOverlapped
630 );
631 */
632 //---------------------------------------------------------------------------
633
634 BOOLEAN PacketSendPacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync)
635 {
636 DWORD BytesTransfered;
637 return WriteFile(AdapterObject->hFile,lpPacket->Buffer,lpPacket->Length,&BytesTransfered,NULL);
638 }
639
640 //---------------------------------------------------------------------------
641
642 BOOLEAN PacketSetMinToCopy(LPADAPTER AdapterObject,int nbytes)
643 {
644 DWORD BytesReturned;
645 return DeviceIoControl(AdapterObject->hFile,pBIOCSMINTOCOPY,&nbytes,4,NULL,0,&BytesReturned,NULL);
646 }
647
648 //---------------------------------------------------------------------------
649
650 BOOLEAN PacketSetMode(LPADAPTER AdapterObject,int mode)
651 {
652 DWORD BytesReturned;
653 return DeviceIoControl(AdapterObject->hFile,pBIOCSMODE,&mode,4,NULL,0,&BytesReturned,NULL);
654 }
655
656 //---------------------------------------------------------------------------
657
658 HANDLE PacketGetReadEvent(LPADAPTER AdapterObject)
659 {
660 return AdapterObject->ReadEvent;
661 }
662
663 //---------------------------------------------------------------------------
664
665 BOOLEAN PacketSetNumWrites(LPADAPTER AdapterObject,int nwrites)
666 {
667 DWORD BytesReturned;
668 return DeviceIoControl(AdapterObject->hFile,pBIOCSWRITEREP,&nwrites,4,NULL,0,&BytesReturned,NULL);
669 }
670
671 //---------------------------------------------------------------------------
672
673 BOOLEAN PacketSetReadTimeout(LPADAPTER AdapterObject,int timeout)
674 {
675 DWORD BytesReturned;
676 int DriverTimeOut=-1;
677
678 AdapterObject->ReadTimeOut=timeout;
679
680 return DeviceIoControl(AdapterObject->hFile,pBIOCSRTIMEOUT,&DriverTimeOut,4,NULL,0,&BytesReturned,NULL);
681 }
682
683 //---------------------------------------------------------------------------
684
685 BOOLEAN PacketSetBuff(LPADAPTER AdapterObject,int dim)
686 {
687 DWORD BytesReturned;
688 return DeviceIoControl(AdapterObject->hFile,pBIOCSETBUFFERSIZE,&dim,4,NULL,0,&BytesReturned,NULL);
689 }
690
691 //---------------------------------------------------------------------------
692
693 BOOLEAN PacketSetBpf(LPADAPTER AdapterObject,struct bpf_program *fp)
694 {
695 DWORD BytesReturned;
696 return DeviceIoControl(AdapterObject->hFile,pBIOCSETF,(char*)fp->bf_insns,fp->bf_len*sizeof(struct bpf_insn),NULL,0,&BytesReturned,NULL);
697 }
698
699 //---------------------------------------------------------------------------
700
701 BOOLEAN PacketGetStats(LPADAPTER AdapterObject,struct bpf_stat *s)
702 {
703 DWORD BytesReturned;
704 return DeviceIoControl(AdapterObject->hFile,pBIOCGSTATS,NULL,0,s,sizeof(struct bpf_stat),&BytesReturned,NULL);
705 }
706
707 //---------------------------------------------------------------------------
708
709 BOOLEAN PacketRequest(LPADAPTER AdapterObject,BOOLEAN Set,PPACKET_OID_DATA OidData)
710 {
711 DWORD BytesReturned;
712 BOOLEAN Result;
713
714 Result=DeviceIoControl(AdapterObject->hFile,(DWORD) Set ? pBIOCSETOID : pBIOCQUERYOID,
715 OidData,sizeof(PACKET_OID_DATA)-1+OidData->Length,OidData,
716 sizeof(PACKET_OID_DATA)-1+OidData->Length,&BytesReturned,NULL);
717
718 // output some debug info
719 ODSEx("PacketRequest, OID=%d ", OidData->Oid);
720 ODSEx("Length=%d ", OidData->Length);
721 ODSEx("Set=%d ", Set);
722 ODSEx("Res=%d\n", Result);
723
724 return Result;
725 }
726
727 //---------------------------------------------------------------------------
728
729 BOOLEAN PacketSetHwFilter(LPADAPTER AdapterObject,ULONG Filter)
730 {
731 BOOLEAN Status;
732 ULONG IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1);
733 PPACKET_OID_DATA OidData;
734
735 OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength);
736 if (OidData == NULL) {
737 ODS("PacketSetHwFilter: GlobalAlloc Failed\n");
738 return FALSE;
739 }
740 OidData->Oid=OID_GEN_CURRENT_PACKET_FILTER;
741 OidData->Length=sizeof(ULONG);
742 *((PULONG)OidData->Data)=Filter;
743 Status=PacketRequest(AdapterObject,TRUE,OidData);
744 GlobalFreePtr(OidData);
745 return Status;
746 }
747
748 //---------------------------------------------------------------------------
749
750 BOOLEAN PacketGetAdapterNames(PTSTR pStr,PULONG BufferSize)
751 {
752 HKEY LinkageKey,AdapKey;
753 DWORD RegKeySize=0;
754 LONG Status;
755 ULONG Result;
756 PTSTR BpStr;
757 char *TTpStr,*DpStr,*DescBuf;
758 LPADAPTER adapter;
759 PPACKET_OID_DATA OidData;
760 int i=0,k,rewind;
761 DWORD dim;
762 TCHAR AdapName[256];
763
764 ODSEx("PacketGetAdapterNames: BufferSize=%d\n",*BufferSize);
765
766 OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,512);
767 if (OidData == NULL) {
768 ODS("PacketGetAdapterNames: GlobalAlloc Failed\n");
769 return FALSE;
770 }
771
772 Status=RegOpenKeyEx(HKEY_LOCAL_MACHINE,
773 TEXT("SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"),
774 0,
775 KEY_READ,
776 &AdapKey);
777
778 // Get the size to allocate for the original device names
779 while((Result=RegEnumKey(AdapKey,i,AdapName,sizeof(AdapName)/2))==ERROR_SUCCESS)
780 {
781 Status=RegOpenKeyEx(AdapKey,AdapName,0,KEY_READ,&LinkageKey);
782 Status=RegOpenKeyEx(LinkageKey,L"Linkage",0,KEY_READ,&LinkageKey);
783 Status=RegQueryValueEx(LinkageKey,L"Export",NULL,NULL,NULL,&dim);
784 i++;
785 if(Status!=ERROR_SUCCESS) continue;
786 RegKeySize+=dim;
787 }
788
789 // Allocate the memory for the original device names
790 ODSEx("Need %d bytes for the names\n", RegKeySize+2);
791 BpStr=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,RegKeySize+2);
792 if (BpStr == NULL || RegKeySize > *BufferSize) {
793 ODS("PacketGetAdapterNames: GlobalAlloc Failed\n");
794 GlobalFreePtr(OidData);
795 return FALSE;
796 }
797
798 k=0;
799 i=0;
800
801 ODS("PacketGetAdapterNames: Cycling through the adapters:\n");
802
803 // Copy the names to the buffer
804 while((Result=RegEnumKey(AdapKey,i,AdapName,sizeof(AdapName)/2))==ERROR_SUCCESS)
805 {
806 WCHAR UpperBindStr[64];
807
808 i++;
809 ODSEx(" %d) ", i);
810
811 Status=RegOpenKeyEx(AdapKey,AdapName,0,KEY_READ,&LinkageKey);
812 Status=RegOpenKeyEx(LinkageKey,L"Linkage",0,KEY_READ,&LinkageKey);
813
814 dim=sizeof(UpperBindStr);
815 Status=RegQueryValueEx(LinkageKey,L"UpperBind",NULL,NULL,(PUCHAR)UpperBindStr,&dim);
816
817 ODSEx("UpperBind=%S ", UpperBindStr);
818
819 if( Status!=ERROR_SUCCESS || _wcsicmp(UpperBindStr,L"NdisWan")==0 ){
820 ODS("Name = SKIPPED\n");
821 continue;
822 }
823
824 dim=RegKeySize-k;
825 Status=RegQueryValueEx(LinkageKey,L"Export",NULL,NULL,(LPBYTE)BpStr+k,&dim);
826 if(Status!=ERROR_SUCCESS){
827 ODS("Name = SKIPPED (error reading the key)\n");
828 continue;
829 }
830
831 ODSEx("Name = %S\n", (LPBYTE)BpStr+k);
832
833 k+=dim-2;
834 }
835
836 CloseHandle(AdapKey);
837
838 #ifdef _DEBUG_TO_FILE
839 //dump BpStr for debug purposes
840 ODS("Dumping BpStr:");
841 {
842 FILE *f;
843 f = fopen("winpcap_debug.txt", "a");
844 for(i=0;i<k;i++){
845 if(!(i%32))fprintf(f, "\n ");
846 fprintf(f, "%c " , *((LPBYTE)BpStr+i));
847 }
848 fclose(f);
849 }
850 ODS("\n");
851 #endif
852
853
854 if (k != 0){
855
856 DescBuf=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, 4096);
857 if (DescBuf == NULL) {
858 GlobalFreePtr (BpStr);
859 GlobalFreePtr(OidData);
860 return FALSE;
861 }
862 DpStr=DescBuf;
863
864 for(i=0,k=0;BpStr[i]!=0 || BpStr[i+1]!=0;){
865
866 if(k+wcslen(BpStr+i)+30 > *BufferSize){
867 // Input buffer too small
868 GlobalFreePtr(OidData);
869 GlobalFreePtr (BpStr);
870 GlobalFreePtr (DescBuf);
871 ODS("PacketGetAdapterNames: Input buffer too small!\n");
872 return FALSE;
873 }
874
875 // Create the device name
876 rewind=k;
877 memcpy(pStr+k,BpStr+i,16);
878 memcpy(pStr+k+8,TEXT("Packet_"),14);
879 i+=8;
880 k+=15;
881 while(BpStr[i-1]!=0){
882 pStr[k++]=BpStr[i++];
883 }
884
885 // Open the adapter
886 adapter=PacketOpenAdapter(pStr+rewind);
887 if(adapter==NULL){
888 k=rewind;
889 continue;
890 }
891
892 // Retrieve the description
893 OidData->Oid = OID_GEN_VENDOR_DESCRIPTION;
894 OidData->Length = 256;
895 ZeroMemory(OidData->Data,256);
896 Status = PacketRequest(adapter,FALSE,OidData);
897 if(Status==0 || ((char*)OidData->Data)[0]==0){
898 k=rewind;
899 continue;
900 }
901
902 ODSEx("Adapter Description=%s\n\n",OidData->Data);
903
904 // Copy the description
905 TTpStr=(char*)(OidData->Data);
906 while(*TTpStr!=0){
907 *DpStr++=*TTpStr++;
908 }
909 *DpStr++=*TTpStr++;
910
911 // Close the adapter
912 PacketCloseAdapter(adapter);
913
914 }
915 *DpStr=0;
916
917 pStr[k++]=0;
918 pStr[k]=0;
919
920 if((ULONG)(DpStr-DescBuf+k) < *BufferSize)
921 memcpy(pStr+k,DescBuf,DpStr-DescBuf);
922 else{
923 GlobalFreePtr(OidData);
924 GlobalFreePtr (BpStr);
925 GlobalFreePtr (DescBuf);
926 ODS("\nPacketGetAdapterNames: ended with failure\n");
927 return FALSE;
928 }
929
930 GlobalFreePtr(OidData);
931 GlobalFreePtr (BpStr);
932 GlobalFreePtr (DescBuf);
933 ODS("\nPacketGetAdapterNames: ended correctly\n");
934 return TRUE;
935 }
936 else{
937 DWORD RegType;
938
939 ODS("Adapters not found under SYSTEM\\CurrentControlSet\\Control\\Class. Using the TCP/IP bindings.\n");
940
941 GlobalFreePtr (BpStr);
942
943 Status=RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Linkage"),0,KEY_READ,&LinkageKey);
944 if (Status == ERROR_SUCCESS)
945 {
946 // Retrieve the length of the key
947 Status=RegQueryValueEx(LinkageKey,TEXT("bind"),NULL,&RegType,NULL,&RegKeySize);
948 // Allocate the buffer
949 BpStr=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,RegKeySize+2);
950 if (BpStr == NULL || RegKeySize > *BufferSize) {
951 GlobalFreePtr(OidData);
952 return FALSE;
953 }
954 Status=RegQueryValueEx(LinkageKey,TEXT("bind"),NULL,&RegType,(LPBYTE)BpStr,&RegKeySize);
955 RegCloseKey(LinkageKey);
956 }
957
958 if (Status==ERROR_SUCCESS){
959
960 DescBuf=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, 4096);
961 if (DescBuf == NULL) {
962 GlobalFreePtr (BpStr);
963 GlobalFreePtr(OidData);
964 return FALSE;
965 }
966 DpStr=DescBuf;
967
968 for(i=0,k=0;BpStr[i]!=0 || BpStr[i+1]!=0;){
969
970 if(k+wcslen(BpStr+i)+30 > *BufferSize){
971 // Input buffer too small
972 GlobalFreePtr(OidData);
973 GlobalFreePtr (BpStr);
974 GlobalFreePtr (DescBuf);
975 return FALSE;
976 }
977
978 // Create the device name
979 rewind=k;
980 memcpy(pStr+k,BpStr+i,16);
981 memcpy(pStr+k+8,TEXT("Packet_"),14);
982 i+=8;
983 k+=15;
984 while(BpStr[i-1]!=0){
985 pStr[k++]=BpStr[i++];
986 }
987
988 // Open the adapter
989 adapter=PacketOpenAdapter(pStr+rewind);
990 if(adapter==NULL){
991 k=rewind;
992 continue;
993 }
994
995 // Retrieve the description
996 OidData->Oid = OID_GEN_VENDOR_DESCRIPTION;
997 OidData->Length = 256;
998 Status = PacketRequest(adapter,FALSE,OidData);
999 if(Status==0 || ((char*)OidData->Data)[0]==0){
1000 k=rewind;
1001 continue;
1002 }
1003
1004 // Copy the description
1005 TTpStr=(char*)(OidData->Data);
1006 while(*TTpStr!=0){
1007 *DpStr++=*TTpStr++;
1008 }
1009 *DpStr++=*TTpStr++;
1010
1011 // Close the adapter
1012 PacketCloseAdapter(adapter);
1013
1014 }
1015 *DpStr=0;
1016
1017 pStr[k++]=0;
1018 pStr[k]=0;
1019
1020 if((ULONG)(DpStr-DescBuf+k) < *BufferSize)
1021 memcpy(pStr+k,DescBuf,DpStr-DescBuf);
1022 else{
1023 GlobalFreePtr(OidData);
1024 GlobalFreePtr (BpStr);
1025 GlobalFreePtr (DescBuf);
1026 return FALSE;
1027 }
1028
1029 GlobalFreePtr(OidData);
1030 GlobalFreePtr (BpStr);
1031 GlobalFreePtr (DescBuf);
1032 return TRUE;
1033 }
1034 else{
1035 MessageBox(NULL,TEXT("Can not find TCP/IP bindings.\nIn order to run the packet capture driver you must install TCP/IP."),szWindowTitle,MB_OK);
1036 ODS("Cannot find the TCP/IP bindings");
1037 return FALSE;
1038 }
1039 }
1040 }
1041
1042 //---------------------------------------------------------------------------
1043
1044 BOOLEAN PacketGetNetInfoEx(LPTSTR AdapterName, npf_if_addr* buffer, PLONG NEntries)
1045 {
1046 char *AdapterNameA;
1047 WCHAR *AdapterNameU;
1048 WCHAR *ifname;
1049 HKEY SystemKey;
1050 HKEY InterfaceKey;
1051 HKEY ParametersKey;
1052 HKEY TcpIpKey;
1053 HKEY UnderTcpKey;
1054 LONG status;
1055 WCHAR String[1024+1];
1056 DWORD RegType;
1057 ULONG BufLen;
1058 DWORD DHCPEnabled;
1059 struct sockaddr_in *TmpAddr, *TmpBroad;
1060 LONG naddrs,nmasks,StringPos;
1061 DWORD ZeroBroadcast;
1062
1063 AdapterNameA = (char*)AdapterName;
1064 if(AdapterNameA[1] != 0) { //ASCII
1065 AdapterNameU = SChar2WChar(AdapterNameA);
1066 AdapterName = AdapterNameU;
1067 } else { //Unicode
1068 AdapterNameU = NULL;
1069 }
1070 ifname = wcsrchr(AdapterName, '\\');
1071 if (ifname == NULL)
1072 ifname = AdapterName;
1073 else
1074 ifname++;
1075 if (wcsncmp(ifname, L"Packet_", 7) == 0)
1076 ifname += 7;
1077
1078 if( RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces"), 0, KEY_READ, &UnderTcpKey) == ERROR_SUCCESS)
1079 {
1080 status = RegOpenKeyEx(UnderTcpKey,ifname,0,KEY_READ,&TcpIpKey);
1081 if (status != ERROR_SUCCESS) {
1082 RegCloseKey(UnderTcpKey);
1083 goto fail;
1084 }
1085 }
1086 else
1087 {
1088
1089 // Query the registry key with the interface's adresses
1090 status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("SYSTEM\\CurrentControlSet"),0,KEY_READ,&SystemKey);
1091 if (status != ERROR_SUCCESS)
1092 goto fail;
1093 status = RegOpenKeyEx(SystemKey,ifname,0,KEY_READ,&InterfaceKey);
1094 if (status != ERROR_SUCCESS) {
1095 RegCloseKey(SystemKey);
1096 goto fail;
1097 }
1098 RegCloseKey(SystemKey);
1099 status = RegOpenKeyEx(InterfaceKey,TEXT("Parameters"),0,KEY_READ,&ParametersKey);
1100 if (status != ERROR_SUCCESS) {
1101 RegCloseKey(InterfaceKey);
1102 goto fail;
1103 }
1104 RegCloseKey(InterfaceKey);
1105 status = RegOpenKeyEx(ParametersKey,TEXT("TcpIp"),0,KEY_READ,&TcpIpKey);
1106 if (status != ERROR_SUCCESS) {
1107 RegCloseKey(ParametersKey);
1108 goto fail;
1109 }
1110 RegCloseKey(ParametersKey);
1111 BufLen = sizeof String;
1112 }
1113
1114 BufLen = 4;
1115 /* Try to detect if the interface has a zero broadcast addr */
1116 status=RegQueryValueEx(TcpIpKey,TEXT("UseZeroBroadcast"),NULL,&RegType,(LPBYTE)&ZeroBroadcast,&BufLen);
1117 if (status != ERROR_SUCCESS)
1118 ZeroBroadcast=0;
1119
1120 BufLen = 4;
1121 /* See if DHCP is used by this system */
1122 status=RegQueryValueEx(TcpIpKey,TEXT("EnableDHCP"),NULL,&RegType,(LPBYTE)&DHCPEnabled,&BufLen);
1123 if (status != ERROR_SUCCESS)
1124 DHCPEnabled=0;
1125
1126
1127 /* Retrieve the adrresses */
1128 if(DHCPEnabled){
1129
1130 BufLen = sizeof String;
1131 // Open the key with the addresses
1132 status = RegQueryValueEx(TcpIpKey,TEXT("DhcpIPAddress"),NULL,&RegType,(LPBYTE)String,&BufLen);
1133 if (status != ERROR_SUCCESS) {
1134 RegCloseKey(TcpIpKey);
1135 goto fail;
1136 }
1137
1138 // scan the key to obtain the addresses
1139 StringPos = 0;
1140 for(naddrs = 0;naddrs <* NEntries;naddrs++){
1141 TmpAddr = (struct sockaddr_in *) &(buffer[naddrs].IPAddress);
1142
1143 if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){
1144 TmpAddr->sin_family = AF_INET;
1145
1146 TmpBroad = (struct sockaddr_in *) &(buffer[naddrs].Broadcast);
1147 TmpBroad->sin_family = AF_INET;
1148 if(ZeroBroadcast==0)
1149 TmpBroad->sin_addr.S_un.S_addr = 0xffffffff; // 255.255.255.255
1150 else
1151 TmpBroad->sin_addr.S_un.S_addr = 0; // 0.0.0.0
1152
1153 while(*(String + StringPos) != 0)StringPos++;
1154 StringPos++;
1155
1156 if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen)
1157 break;
1158 }
1159 else break;
1160 }
1161
1162 BufLen = sizeof String;
1163 // Open the key with the netmasks
1164 status = RegQueryValueEx(TcpIpKey,TEXT("DhcpSubnetMask"),NULL,&RegType,(LPBYTE)String,&BufLen);
1165 if (status != ERROR_SUCCESS) {
1166 RegCloseKey(TcpIpKey);
1167 goto fail;
1168 }
1169
1170 // scan the key to obtain the masks
1171 StringPos = 0;
1172 for(nmasks = 0;nmasks < *NEntries;nmasks++){
1173 TmpAddr = (struct sockaddr_in *) &(buffer[nmasks].SubnetMask);
1174
1175 if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){
1176 TmpAddr->sin_family = AF_INET;
1177
1178 while(*(String + StringPos) != 0)StringPos++;
1179 StringPos++;
1180
1181 if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen)
1182 break;
1183 }
1184 else break;
1185 }
1186
1187 // The number of masks MUST be equal to the number of adresses
1188 if(nmasks != naddrs){
1189 RegCloseKey(TcpIpKey);
1190 goto fail;
1191 }
1192
1193 }
1194 else{
1195
1196 BufLen = sizeof String;
1197 // Open the key with the addresses
1198 status = RegQueryValueEx(TcpIpKey,TEXT("IPAddress"),NULL,&RegType,(LPBYTE)String,&BufLen);
1199 if (status != ERROR_SUCCESS) {
1200 RegCloseKey(TcpIpKey);
1201 goto fail;
1202 }
1203
1204 // scan the key to obtain the addresses
1205 StringPos = 0;
1206 for(naddrs = 0;naddrs < *NEntries;naddrs++){
1207 TmpAddr = (struct sockaddr_in *) &(buffer[naddrs].IPAddress);
1208
1209 if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){
1210 TmpAddr->sin_family = AF_INET;
1211
1212 TmpBroad = (struct sockaddr_in *) &(buffer[naddrs].Broadcast);
1213 TmpBroad->sin_family = AF_INET;
1214 if(ZeroBroadcast==0)
1215 TmpBroad->sin_addr.S_un.S_addr = 0xffffffff; // 255.255.255.255
1216 else
1217 TmpBroad->sin_addr.S_un.S_addr = 0; // 0.0.0.0
1218
1219 while(*(String + StringPos) != 0)StringPos++;
1220 StringPos++;
1221
1222 if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen)
1223 break;
1224 }
1225 else break;
1226 }
1227
1228 BufLen = sizeof String;
1229 // Open the key with the netmasks
1230 status = RegQueryValueEx(TcpIpKey,TEXT("SubnetMask"),NULL,&RegType,(LPBYTE)String,&BufLen);
1231 if (status != ERROR_SUCCESS) {
1232 RegCloseKey(TcpIpKey);
1233 goto fail;
1234 }
1235
1236 // scan the key to obtain the masks
1237 StringPos = 0;
1238 for(nmasks = 0;nmasks <* NEntries;nmasks++){
1239 TmpAddr = (struct sockaddr_in *) &(buffer[nmasks].SubnetMask);
1240
1241 if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){
1242 TmpAddr->sin_family = AF_INET;
1243
1244 while(*(String + StringPos) != 0)StringPos++;
1245 StringPos++;
1246
1247 if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen)
1248 break;
1249 }
1250 else break;
1251 }
1252
1253 // The number of masks MUST be equal to the number of adresses
1254 if(nmasks != naddrs){
1255 RegCloseKey(TcpIpKey);
1256 goto fail;
1257 }
1258
1259 }
1260
1261 *NEntries = naddrs + 1;
1262
1263 RegCloseKey(TcpIpKey);
1264
1265 if (status != ERROR_SUCCESS) {
1266 goto fail;
1267 }
1268
1269
1270 if (AdapterNameU != NULL)
1271 free(AdapterNameU);
1272 return TRUE;
1273
1274 fail:
1275 if (AdapterNameU != NULL)
1276 free(AdapterNameU);
1277 return FALSE;
1278 }
1279
1280 //---------------------------------------------------------------------------
1281
1282 BOOLEAN PacketGetNetInfo(LPTSTR AdapterName, PULONG netp, PULONG maskp)
1283 {
1284 char *AdapterNameA;
1285 WCHAR *AdapterNameU;
1286 WCHAR *ifname;
1287 HKEY SystemKey;
1288 HKEY InterfaceKey;
1289 HKEY ParametersKey;
1290 HKEY TcpIpKey;
1291 LONG status;
1292 WCHAR String[1024+1];
1293 DWORD RegType;
1294 ULONG BufLen;
1295 DWORD DHCPEnabled;
1296 ULONG TAddr,i;
1297
1298 AdapterNameA = (char*)AdapterName;
1299 if(AdapterNameA[1] != 0) { //ASCII
1300 AdapterNameU = SChar2WChar(AdapterNameA);
1301 AdapterName = AdapterNameU;
1302 } else { //Unicode
1303 AdapterNameU = NULL;
1304 }
1305 ifname = wcsrchr(AdapterName, '\\');
1306 if (ifname == NULL)
1307 ifname = AdapterName;
1308 else
1309 ifname++;
1310 if (wcsncmp(ifname, L"Packet_", 7) == 0)
1311 ifname += 7;
1312 status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("SYSTEM\\CurrentControlSet\\Services"),0,KEY_READ,&SystemKey);
1313 if (status != ERROR_SUCCESS)
1314 goto fail;
1315 status = RegOpenKeyEx(SystemKey,ifname,0,KEY_READ,&InterfaceKey);
1316 if (status != ERROR_SUCCESS) {
1317 RegCloseKey(SystemKey);
1318 goto fail;
1319 }
1320 RegCloseKey(SystemKey);
1321 status = RegOpenKeyEx(InterfaceKey,TEXT("Parameters"),0,KEY_READ,&ParametersKey);
1322 if (status != ERROR_SUCCESS) {
1323 RegCloseKey(InterfaceKey);
1324 goto fail;
1325 }
1326 RegCloseKey(InterfaceKey);
1327 status = RegOpenKeyEx(ParametersKey,TEXT("TcpIp"),0,KEY_READ,&TcpIpKey);
1328 if (status != ERROR_SUCCESS) {
1329 RegCloseKey(ParametersKey);
1330 goto fail;
1331 }
1332 RegCloseKey(ParametersKey);
1333
1334 BufLen = 4;
1335 /* See if DHCP is used by this system */
1336 status=RegQueryValueEx(TcpIpKey,TEXT("EnableDHCP"),NULL,&RegType,(LPBYTE)&DHCPEnabled,&BufLen);
1337 if (status != ERROR_SUCCESS)
1338 DHCPEnabled=0;
1339
1340
1341 /* Retrieve the netmask */
1342 if(DHCPEnabled){
1343
1344 BufLen = sizeof String;
1345 status = RegQueryValueEx(TcpIpKey,TEXT("DhcpIPAddress"),NULL,&RegType,(LPBYTE)String,&BufLen);
1346 if (status != ERROR_SUCCESS) {
1347 RegCloseKey(TcpIpKey);
1348 goto fail;
1349 }
1350
1351 TAddr = inet_addrU(String);
1352 // swap bytes for backward compatibility
1353 for(i=0;i<4;i++){
1354 *((char*)netp+i) = *((char*)&TAddr+3-i);
1355 }
1356
1357 BufLen = sizeof String;
1358 status=RegQueryValueEx(TcpIpKey,TEXT("DHCPSubnetMask"),NULL,&RegType,
1359 (LPBYTE)String,&BufLen);
1360
1361 TAddr = inet_addrU(String);
1362 // swap bytes for backward compatibility
1363 for(i=0;i<4;i++){
1364 *((char*)maskp+i) = *((char*)&TAddr+3-i);
1365 }
1366
1367
1368 }
1369 else{
1370
1371 BufLen = sizeof String;
1372 status = RegQueryValueEx(TcpIpKey,TEXT("IPAddress"),NULL,&RegType,(LPBYTE)String,&BufLen);
1373 if (status != ERROR_SUCCESS) {
1374 RegCloseKey(TcpIpKey);
1375 goto fail;
1376 }
1377
1378 TAddr = inet_addrU(String);
1379 // swap bytes for backward compatibility
1380 for(i=0;i<4;i++){
1381 *((char*)netp+i) = *((char*)&TAddr+3-i);
1382 }
1383
1384 BufLen = sizeof String;
1385 status=RegQueryValueEx(TcpIpKey,TEXT("SubnetMask"),NULL,&RegType,
1386 (LPBYTE)String,&BufLen);
1387
1388 TAddr = inet_addrU(String);
1389 // swap bytes for backward compatibility
1390 for(i=0;i<4;i++){
1391 *((char*)maskp+i) = *((char*)&TAddr+3-i);
1392 }
1393
1394
1395 }
1396
1397 if (status != ERROR_SUCCESS) {
1398 RegCloseKey(TcpIpKey);
1399 goto fail;
1400 }
1401
1402
1403 if (AdapterNameU != NULL)
1404 free(AdapterNameU);
1405 return TRUE;
1406
1407 fail:
1408 if (AdapterNameU != NULL)
1409 free(AdapterNameU);
1410 return FALSE;
1411 }