2121#define DISPLAY_ADRESSES 0x1
2222#define DISPLAY_DNS 0x2
2323
24+ #define SOURCE_UNCHANGED 0
25+ #define SOURCE_STATIC 1
26+ #define SOURCE_DHCP 2
27+
28+ #define GATEWAY_NONE 1
29+
30+ #define REGISTER_NONE 1
31+ #define REGISTER_PRIMARY 2
32+ #define REGISTER_BOTH 3
33+
2434static FN_HANDLE_CMD IpSetAddress ;
35+ static FN_HANDLE_CMD IpSetDns ;
2536static FN_HANDLE_CMD IpShowAddresses ;
2637static FN_HANDLE_CMD IpShowConfig ;
2738static FN_HANDLE_CMD IpShowDns ;
3142CMD_ENTRY
3243IpSetCommands [] =
3344{
34- {L"address" , IpSetAddress , IDS_HLP_IP_SET_ADDRESS , IDS_HLP_IP_SET_ADDRESS_EX , 0 }
45+ {L"address" , IpSetAddress , IDS_HLP_IP_SET_ADDRESS , IDS_HLP_IP_SET_ADDRESS_EX , 0 },
46+ {L"dns" , IpSetDns , IDS_HLP_IP_SET_DNS , IDS_HLP_IP_SET_DNS_EX , 0 }
3547};
3648
3749
@@ -407,11 +419,12 @@ IpSetAddress(
407419 {L"mask" , NS_REQ_ZERO , FALSE},
408420 {L"gateway" , NS_REQ_ZERO , FALSE},
409421 {L"gwmetric" , NS_REQ_ZERO , FALSE}};
410- TOKEN_VALUE ptvSource [] = {{L"static" , 1 },
411- {L"dhcp" , 2 }};
422+ TOKEN_VALUE ptvSource [] = {{L"static" , SOURCE_STATIC },
423+ {L"dhcp" , SOURCE_DHCP }};
424+ TOKEN_VALUE ptvGateway [] = {{L"none" , GATEWAY_NONE }};
412425 GUID InterfaceGUID ;
413426 PDWORD pdwTagType = NULL ;
414- DWORD i , dwSource = 0 ;
427+ DWORD i , dwSource = SOURCE_UNCHANGED , dwGateway = 0 ;
415428 BOOL bHaveName = FALSE, bHaveSource = FALSE, bHaveAddress = FALSE,
416429 bHaveMask = FALSE, bHaveGateway = FALSE, bHaveMetric = FALSE;
417430 IN_ADDR Address , Mask , Gateway ;
@@ -545,23 +558,36 @@ IpSetAddress(
545558
546559 case 4 : /* gateway */
547560 DPRINT ("Tag: gateway (%S)\n" , argv [i + dwCurrentIndex ]);
548- Status = RtlIpv4StringToAddressW (argv [i + dwCurrentIndex ],
549- TRUE,
550- & Term ,
551- & Gateway );
552- if (Status != 0 /*STATUS_SUCCESS*/ )
561+ dwError = MatchEnumTag (hDllInstance ,
562+ argv [i + dwCurrentIndex ],
563+ ARRAYSIZE (ptvGateway ),
564+ ptvGateway ,
565+ & dwGateway );
566+ if (dwError == ERROR_SUCCESS )
553567 {
554- DPRINT ("RtlIpv4StringToAddressW() failed (Status 0x%08lx)\n" , Status );
555- PrintMessageFromModule (hDllInstance ,
556- IDS_ERROR_BAD_VALUE ,
557- argv [i + dwCurrentIndex ],
558- pttTags [pdwTagType [i ]].pwszTag );
559- dwError = ERROR_SUPPRESS_OUTPUT ;
560- break ;
568+ pszGateway = NULL ;
569+ pszGwMetric = NULL ;
570+ }
571+ else
572+ {
573+ Status = RtlIpv4StringToAddressW (argv [i + dwCurrentIndex ],
574+ TRUE,
575+ & Term ,
576+ & Gateway );
577+ if (Status != 0 /*STATUS_SUCCESS*/ )
578+ {
579+ DPRINT ("RtlIpv4StringToAddressW() failed (Status 0x%08lx)\n" , Status );
580+ PrintMessageFromModule (hDllInstance ,
581+ IDS_ERROR_BAD_VALUE ,
582+ argv [i + dwCurrentIndex ],
583+ pttTags [pdwTagType [i ]].pwszTag );
584+ dwError = ERROR_SUPPRESS_OUTPUT ;
585+ break ;
586+ }
587+ pszGateway = argv [i + dwCurrentIndex ];
588+ DPRINT ("Gateway: %u.%u.%u.%u\n" ,
589+ Gateway .S_un .S_un_b .s_b1 , Gateway .S_un .S_un_b .s_b2 , Gateway .S_un .S_un_b .s_b3 , Gateway .S_un .S_un_b .s_b4 );
561590 }
562- pszGateway = argv [i + dwCurrentIndex ];
563- DPRINT ("Gateway: %u.%u.%u.%u\n" ,
564- Gateway .S_un .S_un_b .s_b1 , Gateway .S_un .S_un_b .s_b2 , Gateway .S_un .S_un_b .s_b3 , Gateway .S_un .S_un_b .s_b4 );
565591 bHaveGateway = TRUE;
566592 break ;
567593
@@ -598,21 +624,24 @@ IpSetAddress(
598624 if (bHaveName == FALSE)
599625 return ERROR_INVALID_SYNTAX ;
600626
601- if (bHaveSource )
602- {
603- if ((dwSource == 1 ) &&
604- (!bHaveAddress || !bHaveMask ))
605- return ERROR_INVALID_SYNTAX ;
627+ /* We need address and mask, or none of them */
628+ if ((bHaveAddress && !bHaveMask ) ||
629+ (!bHaveAddress && bHaveMask ))
630+ return ERROR_INVALID_SYNTAX ;
606631
607- if ((dwSource == 2 ) &&
608- (bHaveAddress || bHaveMask ))
609- return ERROR_INVALID_SYNTAX ;
610- }
632+ /* If we have an address, we need a source */
633+ if (bHaveAddress && !bHaveSource )
634+ return ERROR_INVALID_SYNTAX ;
611635
636+ /* We need gateway and metric, or none of them */
612637 if ((bHaveGateway && !bHaveMetric ) ||
613638 (!bHaveGateway && bHaveMetric ))
614639 return ERROR_INVALID_SYNTAX ;
615640
641+ /* If we have a static source, we need an address or a gateway */
642+ if ((dwSource == SOURCE_STATIC ) && !bHaveAddress && !bHaveGateway )
643+ return ERROR_INVALID_SYNTAX ;
644+
616645 hr = GetInterfaceProperties (& InterfaceGUID , & pProperties );
617646 if (FAILED (hr ))
618647 {
@@ -629,7 +658,7 @@ IpSetAddress(
629658 goto done ;
630659 }
631660
632- if (dwSource == 1 )
661+ if (dwSource == SOURCE_STATIC )
633662 {
634663 /* STATIC */
635664 NewProperties .dwDhcp = 0 ;
@@ -650,7 +679,7 @@ IpSetAddress(
650679 L"0.0.0.0" , L"0" );
651680 }
652681 }
653- else if (dwSource == 2 )
682+ else if (dwSource == SOURCE_DHCP )
654683 {
655684 /* DHCP */
656685 if (pProperties -> dwDhcp )
@@ -684,6 +713,223 @@ IpSetAddress(
684713 return dwError ;
685714}
686715
716+ static
717+ DWORD
718+ WINAPI
719+ IpSetDns (
720+ LPCWSTR pwszMachine ,
721+ LPWSTR * argv ,
722+ DWORD dwCurrentIndex ,
723+ DWORD dwArgCount ,
724+ DWORD dwFlags ,
725+ LPCVOID pvData ,
726+ BOOL * pbDone )
727+ {
728+ TAG_TYPE pttTags [] = {{L"name" , NS_REQ_ZERO , FALSE},
729+ {L"source" , NS_REQ_ZERO , FALSE},
730+ {L"addr" , NS_REQ_ZERO , FALSE},
731+ {L"register" , NS_REQ_ZERO , FALSE}};
732+ TOKEN_VALUE ptvSource [] = {{L"static" , SOURCE_STATIC },
733+ {L"dhcp" , SOURCE_DHCP }};
734+ TOKEN_VALUE ptvRegister [] = {{L"none" , REGISTER_NONE },
735+ {L"primary" , REGISTER_PRIMARY },
736+ {L"both" , REGISTER_BOTH }};
737+ GUID InterfaceGUID ;
738+ PDWORD pdwTagType = NULL ;
739+ DWORD i , dwSource = SOURCE_UNCHANGED ;
740+ BOOL bHaveName = FALSE, bHaveSource = FALSE, bHaveAddress = FALSE /*,
741+ bHaveRegister = FALSE */ ;
742+ IN_ADDR Address ;
743+ PWSTR pszName = NULL , pszAddress = NULL ;
744+ PWSTR pszParameterBuffer = NULL ;
745+ PCWSTR Term ;
746+ DWORD dwRegister = REGISTER_NONE ;
747+ PTCPIP_PROPERTIES pProperties = NULL ;
748+ TCPIP_PROPERTIES NewProperties ;
749+ HRESULT hr ;
750+ NTSTATUS Status ;
751+ DWORD dwError = ERROR_SUCCESS ;
752+
753+ DPRINT ("IpSetDns()\n" );
754+
755+ pdwTagType = HeapAlloc (GetProcessHeap (),
756+ 0 ,
757+ (dwArgCount - dwCurrentIndex ) * sizeof (DWORD ));
758+ if (pdwTagType == NULL )
759+ {
760+ return ERROR_NOT_ENOUGH_MEMORY ;
761+ }
762+
763+ dwError = MatchTagsInCmdLine (hDllInstance ,
764+ argv ,
765+ dwCurrentIndex ,
766+ dwArgCount ,
767+ pttTags ,
768+ ARRAYSIZE (pttTags ),
769+ pdwTagType );
770+ if (dwError != ERROR_SUCCESS )
771+ {
772+ DPRINT1 ("MatchTagsInCmdLine() failed (Error %lu)\n" , dwError );
773+ HeapFree (GetProcessHeap (), 0 , pdwTagType );
774+ return dwError ;
775+ }
776+
777+ for (i = 0 ; i < (dwArgCount - dwCurrentIndex ); i ++ )
778+ {
779+ DPRINT ("Tag %lu: %lu\n" , i , pdwTagType [i ]);
780+
781+ switch (pdwTagType [i ])
782+ {
783+ case 0 : /* name */
784+ DPRINT ("Tag: name (%S)\n" , argv [i + dwCurrentIndex ]);
785+ dwError = NhGetGuidFromInterfaceName (argv [i + dwCurrentIndex ],
786+ & InterfaceGUID ,
787+ 0 , 0 );
788+ if (dwError != ERROR_SUCCESS )
789+ {
790+ DPRINT ("NhGetGuidFromInterfaceName() failed (Error %lu)\n" , dwError );
791+ PrintMessageFromModule (hDllInstance ,
792+ IDS_ERROR_INVALID_INTERFACE ,
793+ argv [i + dwCurrentIndex ]);
794+ dwError = ERROR_SUPPRESS_OUTPUT ;
795+ break ;
796+ }
797+ pszName = argv [i + dwCurrentIndex ];
798+ DPRINT ("Interface: {%08lx-%04hx-%04hx-%02x%02x-%02x%02x%02x%02x%02x%02x}\n" ,
799+ InterfaceGUID .Data1 , InterfaceGUID .Data2 , InterfaceGUID .Data3 , InterfaceGUID .Data4 [0 ], InterfaceGUID .Data4 [1 ],
800+ InterfaceGUID .Data4 [2 ], InterfaceGUID .Data4 [3 ], InterfaceGUID .Data4 [4 ], InterfaceGUID .Data4 [5 ], InterfaceGUID .Data4 [6 ], InterfaceGUID .Data4 [7 ]);
801+ bHaveName = TRUE;
802+ break ;
803+
804+ case 1 : /* source */
805+ DPRINT ("Tag: source (%S)\n" , argv [i + dwCurrentIndex ]);
806+ dwError = MatchEnumTag (hDllInstance ,
807+ argv [i + dwCurrentIndex ],
808+ ARRAYSIZE (ptvSource ),
809+ ptvSource ,
810+ & dwSource );
811+ if (dwError != ERROR_SUCCESS )
812+ {
813+ DPRINT ("MatchEnumTag() failed (Error %lu)\n" , dwError );
814+ PrintMessageFromModule (hDllInstance ,
815+ IDS_ERROR_BAD_VALUE ,
816+ argv [i + dwCurrentIndex ],
817+ pttTags [pdwTagType [i ]].pwszTag );
818+ dwError = ERROR_SUPPRESS_OUTPUT ;
819+ break ;
820+ }
821+ DPRINT ("Source: %lu\n" , dwSource );
822+ bHaveSource = TRUE;
823+ break ;
824+
825+ case 2 : /* addr */
826+ DPRINT ("Tag: addr (%S)\n" , argv [i + dwCurrentIndex ]);
827+ Status = RtlIpv4StringToAddressW (argv [i + dwCurrentIndex ],
828+ TRUE,
829+ & Term ,
830+ & Address );
831+ if (Status != 0 /*STATUS_SUCCESS*/ )
832+ {
833+ DPRINT ("RtlIpv4StringToAddressW() failed (Status 0x%08lx)\n" , Status );
834+ PrintMessageFromModule (hDllInstance ,
835+ IDS_ERROR_BAD_VALUE ,
836+ argv [i + dwCurrentIndex ],
837+ pttTags [pdwTagType [i ]].pwszTag );
838+ dwError = ERROR_SUPPRESS_OUTPUT ;
839+ break ;
840+ }
841+ DPRINT ("IP Address: %u.%u.%u.%u\n" ,
842+ Address .S_un .S_un_b .s_b1 , Address .S_un .S_un_b .s_b2 , Address .S_un .S_un_b .s_b3 , Address .S_un .S_un_b .s_b4 );
843+ pszAddress = argv [i + dwCurrentIndex ];
844+ DPRINT ("IP Address: %S\n" , pszAddress );
845+ bHaveAddress = TRUE;
846+ break ;
847+
848+ case 3 : /* register */
849+ DPRINT ("Tag: register (%S)\n" , argv [i + dwCurrentIndex ]);
850+ dwError = MatchEnumTag (hDllInstance ,
851+ argv [i + dwCurrentIndex ],
852+ ARRAYSIZE (ptvRegister ),
853+ ptvRegister ,
854+ & dwRegister );
855+ if (dwError != ERROR_SUCCESS )
856+ {
857+ DPRINT ("MatchEnumTag() failed (Error %lu)\n" , dwError );
858+ PrintMessageFromModule (hDllInstance ,
859+ IDS_ERROR_BAD_VALUE ,
860+ argv [i + dwCurrentIndex ],
861+ pttTags [pdwTagType [i ]].pwszTag );
862+ dwError = ERROR_SUPPRESS_OUTPUT ;
863+ break ;
864+ }
865+ DPRINT ("Register: %lu\n" , dwRegister );
866+ // bHaveRegister = TRUE;
867+ break ;
868+
869+ default :
870+ DPRINT1 ("Unknown tag type %lu\n" , pdwTagType [i ]);
871+ break ;
872+ }
873+ }
874+
875+ if (pdwTagType )
876+ HeapFree (GetProcessHeap (), 0 , pdwTagType );
877+
878+ if (dwError != ERROR_SUCCESS )
879+ return dwError ;
880+
881+ /* Check parameters */
882+
883+ /* The name and source arguments are mandatory */
884+ if (!bHaveName || !bHaveSource )
885+ return ERROR_INVALID_SYNTAX ;
886+
887+ /* If we have a static source, we need to have an address */
888+ if ((dwSource == SOURCE_STATIC ) && (!bHaveAddress ))
889+ return ERROR_INVALID_SYNTAX ;
890+
891+ /* If we have a dhcp source, we must not have an address */
892+ if ((dwSource == SOURCE_DHCP ) && (bHaveAddress ))
893+ return ERROR_INVALID_SYNTAX ;
894+
895+ hr = GetInterfaceProperties (& InterfaceGUID , & pProperties );
896+ if (FAILED (hr ))
897+ {
898+ PrintMessageFromModule (hDllInstance ,
899+ IDS_ERROR_GET_PROPERTIES ,
900+ pszName );
901+ return ERROR_SUPPRESS_OUTPUT ;
902+ }
903+
904+ pszParameterBuffer = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY , BUFFER_SIZE * sizeof (WCHAR ));
905+ if (pszParameterBuffer == NULL )
906+ {
907+ dwError = ERROR_NOT_ENOUGH_MEMORY ;
908+ goto done ;
909+ }
910+
911+ StringCchPrintfW (pszParameterBuffer , BUFFER_SIZE ,
912+ L"DNS=%s;DynamicUpdate=%s;NameRegistration=%s;" ,
913+ (pszAddress ) ? pszAddress : L"" ,
914+ ((dwRegister == REGISTER_BOTH ) || (dwRegister == REGISTER_PRIMARY )) ? L"1" : L"0" ,
915+ (dwRegister == REGISTER_BOTH ) ? L"1" : L"0" );
916+
917+ NewProperties .dwDhcp = pProperties -> dwDhcp ;
918+ NewProperties .pszIpAddress = pProperties -> pszIpAddress ;
919+ NewProperties .pszSubnetMask = pProperties -> pszSubnetMask ;
920+ NewProperties .pszParameters = pszParameterBuffer ;
921+
922+ SetInterfaceProperties (& InterfaceGUID , & NewProperties );
923+
924+ done :
925+ if (pszParameterBuffer )
926+ HeapFree (GetProcessHeap (), 0 , pszParameterBuffer );
927+
928+ CoTaskMemFree (pProperties );
929+ pProperties = NULL ;
930+
931+ return dwError ;
932+ }
687933
688934static
689935DWORD
0 commit comments