02464 :
02465
02466 The
main entry point
for the user process.
02467 This process will prompt
the user
for the action desired. This
02468 includes starting performance, stopping performance, and retreiving
02469 performance data collected by
the FT driver.
02470
02471 Arguments:
02472
02473 Command line:
02474 No options.
02475
02476 Return Value:
02477
02478 NONE
02479
02480 --*/
02481
02482 {
02483
NTSTATUS status;
02484 BOOLEAN batch;
02485 PUCHAR argumentString;
02486
int commandCode;
02487 HANDLE keyHandle;
02488
02489
02490 status =
FtOpenKey(&keyHandle, REGISTRY_BASE);
02491
02492
if (!
NT_SUCCESS(status)) {
02493
02494 printf(
"readreg: Unable to open registry base (0x%x)\n", status);
02495
exit(1);
02496 }
02497
02498
sprintf(CurrentDirectory,
02499 REGISTRY_BASE);
02500
02501
02502
02503
02504
02505 batch =
FALSE;
02506
02507
02508
if (!batch) {
02509 printf(
"FT registry edit utility. %s:\n", Version);
02510 }
02511
02512
while(1) {
02513
while ((commandCode =
GetCommand(batch,
02514 &argumentString)) ==
INVALID) {
02515
02516
02517
02518
02519
02520 }
02521
02522
if (
Debug) {
02523 printf(
"Command code == %d, argumentString = %s\n",
02524 commandCode,
02525 (argumentString == NULL) ?
"(none)" : argumentString);
02526 }
02527
02528
switch (commandCode) {
02529
02530
case DIRLONG:
02531
02532
Directory(keyHandle, (BOOLEAN) TRUE);
02533
break;
02534
02535
case DIR:
02536
02537
Directory(keyHandle, (BOOLEAN) FALSE);
02538
break;
02539
02540
case CREATE:
02541 {
02542 ULONG index;
02543 PUCHAR keyClass;
02544 BOOLEAN classAllocated =
FALSE;
02545
02546
if (argumentString ==
NULL) {
02547 argumentString =
GetArgumentString(batch,
02548
"Key Name = ",
02549 (BOOLEAN) FALSE);
02550 }
02551
02552
if (argumentString ==
NULL) {
02553
break;
02554 }
02555
02556
sprintf(WorkingDirectory,
02557
"%s\\%s",
02558 CurrentDirectory,
02559 argumentString);
02560
02561 argumentString =
GetArgumentString(batch,
02562
"Key Class = ",
02563 (BOOLEAN) FALSE);
02564
02565
if (argumentString ==
NULL) {
02566 keyClass =
"Default Class";
02567 }
else {
02568 keyClass = (PUCHAR) malloc(
strlen(argumentString) + FUDGE);
02569 classAllocated =
TRUE;
02570
02571
sprintf(keyClass,
02572
"%s",
02573 argumentString);
02574 }
02575
02576 argumentString =
GetArgumentString(batch,
02577
"Index = ",
02578 (BOOLEAN) TRUE);
02579
02580
if (argumentString ==
NULL) {
02581 index = 1;
02582 }
else {
02583 index =
ParseArgumentNumeric(&argumentString);
02584 }
02585
02586
if (
Debug) {
02587 printf(
"Creating key %s, index %d with class %s\n",
02588 WorkingDirectory,
02589 index,
02590 keyClass);
02591 }
02592
02593 status =
FtCreateKey(WorkingDirectory,
02594 keyClass,
02595 index);
02596
02597
if (!
NT_SUCCESS(status)) {
02598
02599 printf(
"Could not create key %s (0x%x).\n",
02600 WorkingDirectory,
02601 status);
02602 }
02603
02604
if (classAllocated ==
TRUE) {
02605 free(keyClass);
02606 }
02607
02608
break;
02609 }
02610
02611
case LIST:
02612
02613
List(keyHandle,
02614 argumentString);
02615
break;
02616
02617
case CHDIR:
02618
02619
NtClose(keyHandle);
02620
02621
if (argumentString ==
NULL) {
02622
02623 argumentString =
GetArgumentString(batch,
02624
"New location = ",
02625 (BOOLEAN) TRUE);
02626 }
02627
02628
if (argumentString !=
NULL) {
02629
02630
if (*argumentString ==
'\\') {
02631
02632
02633
02634
02635
02636
02637
02638
sprintf(WorkingDirectory,
02639
"%s",
02640 argumentString);
02641
02642 }
else {
02643
02644
while ((*argumentString ==
'.') &&
02645 (*(argumentString + 1) ==
'.')) {
02646
02647
if ((*(argumentString + 2) ==
'\\') ||
02648 (*(argumentString + 2) ==
'\0')) {
02649
02650 PUCHAR cptr =
CurrentDirectory;
02651
02652
02653
02654
02655
02656 argumentString += 2;
02657
02658
02659
02660
02661
02662
while (*cptr !=
'\0') {
02663 cptr++;
02664 }
02665
02666
02667
02668
02669
02670
while (*cptr !=
'\\') {
02671 cptr--;
02672 }
02673
02674
if (cptr ==
CurrentDirectory) {
02675
02676
02677
02678
02679
02680
02681
continue;
02682 }
02683
02684
02685
02686
02687
02688 *cptr =
'\0';
02689
02690
if (*argumentString ==
'\0') {
02691
02692
02693
02694
02695
02696
break;
02697 }
02698
02699
02700
02701
02702
02703 argumentString++;
02704
02705 }
else {
02706
02707
02708
02709
02710
02711
break;
02712 }
02713 }
02714
02715
if (*argumentString !=
'\0') {
02716
sprintf(WorkingDirectory,
02717
"%s\\%s",
02718 CurrentDirectory,
02719 argumentString);
02720 }
else {
02721
sprintf(WorkingDirectory,
02722
"%s",
02723 CurrentDirectory);
02724 }
02725 }
02726
02727 status =
FtOpenKey(&keyHandle,
02728 WorkingDirectory);
02729
02730
if (
NT_SUCCESS(status)) {
02731
02732
sprintf(CurrentDirectory,
02733
"%s",
02734 WorkingDirectory);
02735 }
else {
02736
02737 (
VOID)
FtOpenKey(&keyHandle,
02738 CurrentDirectory);
02739
02740
02741
02742
02743 }
02744
02745 }
02746
02747
break;
02748
02749
case HELP:
02750 {
02751
int i;
02752
02753 printf(
"Valid commands are:\n");
02754
02755
for (i = 0;
Commands[i] !=
NULL; i++) {
02756 printf(
" %10s - %s\n",
02757 Commands[i],
02758 CommandHelp[CommandMap[i]]);
02759 }
02760
break;
02761 }
02762
02763
case QUIT:
02764
02765
exit(0);
02766
break;
02767
02768
case DDEBUG:
02769
02770
if (argumentString ==
NULL) {
02771
02772
if (
Debug) {
02773
02774 printf(
"Debug turned off.\n");
02775
Debug = 0;
02776 }
else {
02777
02778
Debug = 1;
02779 }
02780 }
else {
02781
02782
Debug = atoi(argumentString);
02783 printf(
"Debug set to %d\n", Debug);
02784 }
02785
break;
02786
02787
case SETVALUE:
02788 {
02789
int i;
02790 BOOLEAN convertToUnicode =
FALSE;
02791 PUCHAR valueName;
02792 PUCHAR valueData;
02793 ULONG valueLength;
02794 ULONG valueWord;
02795 PVOID valuePtr;
02796 ULONG
type =
DEFAULT_TYPE;
02797 STRING valueString;
02798 UNICODE_STRING unicodeValue;
02799 BOOLEAN dataAllocated =
FALSE;
02800 BOOLEAN unicodeAllocated =
FALSE;
02801
02802
if (argumentString ==
NULL) {
02803
02804 argumentString =
GetArgumentString(batch,
02805
"Value Name = ",
02806 (BOOLEAN) FALSE);
02807 }
02808
02809
if (argumentString ==
NULL) {
02810
02811
break;
02812 }
02813
02814 valueName = (PUCHAR) malloc(
strlen(argumentString) + FUDGE);
02815
02816
sprintf(valueName,
02817
"%s",
02818 argumentString);
02819
02820
02821
02822
02823
02824
for (i = 0;
TypeNames[i] !=
NULL; i++) {
02825
02826 printf(
"%d - %s\n", TypeNumbers[i], TypeNames[i]);
02827 }
02828 printf(
"# - Other numbers are user defined\n");
02829 argumentString =
GetArgumentString(batch,
02830
"Numeric value for type = ",
02831 (BOOLEAN) TRUE);
02832
02833
if (argumentString !=
NULL) {
02834
type =
ParseArgumentNumeric(&argumentString);
02835 }
02836
02837
switch(
type)
02838 {
02839
default:
02840
case REG_SZ:
02841
if (
type == REG_SZ) {
02842 convertToUnicode =
TRUE;
02843 printf(
"Typed in string will be converted to unicode...\n");
02844 argumentString =
GetArgumentString(batch,
02845
"Value Data = ",
02846 (BOOLEAN) FALSE);
02847 }
else {
02848 printf(
"For now the data must be typed in...\n");
02849 argumentString =
GetArgumentString(batch,
02850
"Value Data = ",
02851 (BOOLEAN) FALSE);
02852 }
02853
02854
if (argumentString ==
NULL) {
02855 valueData =
"Default Data";
02856 valueLength =
strlen(valueData);
02857 }
else {
02858 valueData = (PUCHAR) malloc(
strlen(argumentString) + FUDGE);
02859 dataAllocated =
TRUE;
02860
sprintf(valueData,
02861
"%s",
02862 argumentString);
02863
if (convertToUnicode ==
TRUE) {
02864
RtlInitString(&valueString,
02865 valueData);
02866
RtlAnsiStringToUnicodeString(&unicodeValue,
02867 &valueString,
02868 (BOOLEAN) TRUE);
02869 unicodeAllocated =
TRUE;
02870 valueLength = unicodeValue.Length + 2;
02871 }
else {
02872 valueLength =
strlen(valueData);
02873 }
02874 }
02875
02876
break;
02877
02878
case REG_DWORD:
02879 argumentString =
GetArgumentString(batch,
02880
"Value Data Word = ",
02881 (BOOLEAN) TRUE);
02882
if (argumentString ==
NULL) {
02883 valueWord = 0;
02884 }
else {
02885 valueWord =
ParseArgumentNumeric(&argumentString);
02886 }
02887
02888 valueLength =
sizeof(ULONG);
02889
break;
02890 }
02891
02892
switch (
type) {
02893
02894
case REG_DWORD:
02895 valuePtr = (PVOID) &valueWord;
02896
break;
02897
02898
case REG_SZ:
02899 valuePtr = (PVOID) unicodeValue.Buffer;
02900
break;
02901
02902
default:
02903 valuePtr = (PVOID) valueData;
02904
break;
02905 }
02906 status =
FtSetValue(keyHandle,
02907 valueName,
02908 valuePtr,
02909 valueLength,
02910 type);
02911
02912
if (!
NT_SUCCESS(status)) {
02913 printf(
"Could not set value %s (0x%x).\n", valueName, status);
02914 }
02915
02916 free(valueName);
02917
if (dataAllocated ==
TRUE) {
02918 free(valueData);
02919 }
02920
if (unicodeAllocated ==
TRUE) {
02921
RtlFreeUnicodeString(&unicodeValue);
02922 }
02923
break;
02924 }
02925
02926
case DELKEY:
02927 {
02928
if (argumentString ==
NULL) {
02929
02930 argumentString =
GetArgumentString(batch,
02931
"Key Name = ",
02932 (BOOLEAN) TRUE);
02933 }
02934
02935
if (argumentString ==
NULL) {
02936
02937
break;
02938 }
02939
02940
sprintf(WorkingDirectory,
02941
"%s\\%s",
02942 CurrentDirectory,
02943 argumentString);
02944
02945 status =
FtDeleteKey(WorkingDirectory);
02946
02947
if (!
NT_SUCCESS(status)) {
02948 printf(
"Unable to delete key %s (0x%x)\n",
02949 WorkingDirectory,
02950 status);
02951 }
02952
02953
break;
02954 }
02955
02956
case DELVALUE:
02957 {
02958
if (argumentString ==
NULL) {
02959
02960 argumentString =
GetArgumentString(batch,
02961
"Key Name = ",
02962 (BOOLEAN) TRUE);
02963 }
02964
02965
if (argumentString ==
NULL) {
02966
02967
break;
02968 }
02969
02970 status =
FtDeleteValue(keyHandle,
02971 argumentString);
02972
02973
if (!
NT_SUCCESS(status)) {
02974
02975 printf(
"Unable to delete value %s (0x%x)\n",
02976 argumentString,
02977 status);
02978 }
02979
break;
02980 }
02981
02982
case INLONG:
02983
DumpControl =
InLongs;
02984
break;
02985
02986
case INSHORT:
02987
DumpControl =
InShorts;
02988
break;
02989
02990
case INBYTE:
02991
DumpControl =
InBytes;
02992
break;
02993
02994
case DUMP:
02995
02996
if (
ForceDump) {
02997
ForceDump = 0;
02998 }
else {
02999
ForceDump++;
03000 }
03001
break;
03002
03003
case DISKREG:
03004
DiskDump();
03005
break;
03006
03007
case FIXDISK:
03008
FixDisk();
03009
break;
03010
03011
case RESTORE:
03012 {
03013 ULONG
type;
03014 ULONG group;
03015 ULONG member;
03016
03017 printf(
"FT types that can be restored are:\n");
03018 printf(
"\t%d - for Mirrors\n", Mirror);
03019 printf(
"\t%d - for Stripes with parity\n", StripeWithParity);
03020
03021
03022
03023
03024
03025
if (argumentString ==
NULL) {
03026 argumentString =
GetArgumentString(batch,
03027
"FT volume type = ",
03028 (BOOLEAN) TRUE);
03029 }
03030
if (argumentString !=
NULL) {
03031
type =
ParseArgumentNumeric(&argumentString);
03032 }
else {
03033
break;
03034 }
03035
03036
03037
03038
03039
03040
if (argumentString ==
NULL) {
03041 argumentString =
GetArgumentString(batch,
03042
"FT group number = ",
03043 (BOOLEAN) TRUE);
03044 }
03045
if (argumentString !=
NULL) {
03046 group =
ParseArgumentNumeric(&argumentString);
03047 }
else {
03048
break;
03049 }
03050
03051
03052
03053
03054
03055
if (argumentString ==
NULL) {
03056 argumentString =
GetArgumentString(batch,
03057
"FT member number = ",
03058 (BOOLEAN) TRUE);
03059 }
03060
if (argumentString !=
NULL) {
03061 member =
ParseArgumentNumeric(&argumentString);
03062 }
else {
03063
break;
03064 }
03065
03066
RestoreOrphan(type, group, member);
03067
break;
03068 }
03069
03070
case DRIVERS:
03071
NotImplemented();
03072
03073
break;
03074
03075
case ORPHAN:
03076 {
03077 ULONG
type;
03078 ULONG group;
03079 ULONG member;
03080
03081 printf(
"FT types that can be orphaned are:\n");
03082 printf(
"\t%d - for Mirrors\n", Mirror);
03083 printf(
"\t%d - for Stripes with parity\n", StripeWithParity);
03084
03085
03086
03087
03088
03089
if (argumentString ==
NULL) {
03090 argumentString =
GetArgumentString(batch,
03091
"FT volume type = ",
03092 (BOOLEAN) TRUE);
03093 }
03094
if (argumentString !=
NULL) {
03095
type =
ParseArgumentNumeric(&argumentString);
03096 }
else {
03097
break;
03098 }
03099
03100
03101
03102
03103
03104
if (argumentString ==
NULL) {
03105 argumentString =
GetArgumentString(batch,
03106
"FT group number = ",
03107 (BOOLEAN) TRUE);
03108 }
03109
if (argumentString !=
NULL) {
03110 group =
ParseArgumentNumeric(&argumentString);
03111 }
else {
03112
break;
03113 }
03114
03115
03116
03117
03118
03119
if (argumentString ==
NULL) {
03120 argumentString =
GetArgumentString(batch,
03121
"FT member number = ",
03122 (BOOLEAN) TRUE);
03123 }
03124
if (argumentString !=
NULL) {
03125 member =
ParseArgumentNumeric(&argumentString);
03126 }
else {
03127
break;
03128 }
03129
03130
OrphanMember(type, group, member);
03131
break;
03132 }
03133
03134
case REGEN:
03135 {
03136 ULONG
type;
03137 ULONG group;
03138 ULONG member;
03139
03140 printf(
"FT types that can be regenerated are:\n");
03141 printf(
"\t%d - for Mirrors\n", Mirror);
03142 printf(
"\t%d - for Stripes with parity\n", StripeWithParity);
03143
03144
03145
03146
03147
03148
if (argumentString ==
NULL) {
03149 argumentString =
GetArgumentString(batch,
03150
"FT volume type = ",
03151 (BOOLEAN) TRUE);
03152 }
03153
if (argumentString !=
NULL) {
03154
type =
ParseArgumentNumeric(&argumentString);
03155 }
else {
03156
break;
03157 }
03158
03159
03160
03161
03162
03163
if (argumentString ==
NULL) {
03164 argumentString =
GetArgumentString(batch,
03165
"FT group number = ",
03166 (BOOLEAN) TRUE);
03167 }
03168
if (argumentString !=
NULL) {
03169 group =
ParseArgumentNumeric(&argumentString);
03170 }
else {
03171
break;
03172 }
03173
03174
03175
03176
03177
03178
if (argumentString ==
NULL) {
03179 argumentString =
GetArgumentString(batch,
03180
"FT member number = ",
03181 (BOOLEAN) TRUE);
03182 }
03183
if (argumentString !=
NULL) {
03184 member =
ParseArgumentNumeric(&argumentString);
03185 }
else {
03186
break;
03187 }
03188
03189
RegenerateMember(type, group, member);
03190
break;
03191 }
03192
03193
case INIT:
03194 {
03195 ULONG
type;
03196 ULONG group;
03197 ULONG member;
03198
03199 printf(
"Only stripes with parity are initialized.\n");
03200
03201
03202
03203
03204
03205
if (argumentString ==
NULL) {
03206 argumentString =
GetArgumentString(batch,
03207
"Parity stripe group number = ",
03208 (BOOLEAN) TRUE);
03209 }
03210
if (argumentString !=
NULL) {
03211 group =
ParseArgumentNumeric(&argumentString);
03212 }
else {
03213
break;
03214 }
03215
03216
ChangeMemberState(StripeWithParity,
03217 group,
03218 0,
03219 Initializing);
03220
break;
03221 }
03222
03223
case MAKEFT:
03224 {
03225 ULONG
type;
03226 ULONG group;
03227 ULONG member;
03228 ULONG disk;
03229 ULONG partition;
03230 PDISK_CONFIG_HEADER configHeader;
03231 BOOLEAN doUpdate =
TRUE;
03232
03233 configHeader =
GetDiskInfo();
03234
if (configHeader ==
NULL) {
03235
break;
03236 }
03237 printf(
"\t%d for Mirrors\n", Mirror);
03238 printf(
"\t%d for Stripe Set\n", Stripe);
03239 printf(
"\t%d for Stripe with parity\n", StripeWithParity);
03240 printf(
"\t%d for Volume Set\n", VolumeSet);
03241
03242
if (argumentString ==
NULL) {
03243 argumentString =
GetArgumentString(batch,
03244
"Which FT set to create? ",
03245 (BOOLEAN) TRUE);
03246 }
03247
if (argumentString !=
NULL) {
03248
type =
ParseArgumentNumeric(&argumentString);
03249 }
else {
03250
break;
03251 }
03252
03253
if (argumentString ==
NULL) {
03254 argumentString =
GetArgumentString(batch,
03255
"Please give an FT group # - ",
03256 (BOOLEAN) TRUE);
03257 }
03258
if (argumentString !=
NULL) {
03259 group =
ParseArgumentNumeric(&argumentString);
03260 }
else {
03261
break;
03262 }
03263
03264
for (member = 0;
TRUE; member++) {
03265 printf(
"Information for member %d\n", member);
03266
03267
if (argumentString ==
NULL) {
03268 argumentString =
GetArgumentString(batch,
03269
"Disk Number = ",
03270 (BOOLEAN) TRUE);
03271 }
03272
03273
if (argumentString !=
NULL) {
03274 disk =
ParseArgumentNumeric(&argumentString);
03275 }
else {
03276
break;
03277 }
03278
03279
if (argumentString ==
NULL) {
03280 argumentString =
GetArgumentString(batch,
03281
"Partition Number = ",
03282 (BOOLEAN) TRUE);
03283 }
03284
03285
if (argumentString !=
NULL) {
03286 partition =
ParseArgumentNumeric(&argumentString);
03287 }
else {
03288
break;
03289 }
03290
03291
if (
CreateFtMember(configHeader, disk, partition, type, group, member) ==
FALSE) {
03292 printf(
"Failed to change member state\n");
03293 printf(
"No update will be made\n");
03294 doUpdate =
FALSE;
03295
break;
03296 }
03297 }
03298
if (doUpdate ==
TRUE) {
03299 PDISK_REGISTRY diskRegistry;
03300 diskRegistry = (PDISK_REGISTRY)
03301 ((PUCHAR) configHeader + configHeader->DiskInformationOffset);
03302 DiskRegistrySet(diskRegistry);
03303 }
03304 free(configHeader);
03305
break;
03306 }
03307
03308
default:
03309
03310 printf(
"WDF homer?!?\n");
03311
break;
03312 }
03313 }
03314 }
}