Subversion Repositories oidplus

Rev

Rev 741 | Rev 743 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 741 Rev 742
1
program OIDPLUS;
1
program OIDPLUS;
2
 
2
 
3
(************************************************)
3
(************************************************)
4
(* OIDPLUS.PAS                                  *)
4
(* OIDPLUS.PAS                                  *)
5
(* Author:   Daniel Marschall                   *)
5
(* Author:   Daniel Marschall                   *)
6
(* Revision: 2022-02-14                         *)
6
(* Revision: 2022-02-14                         *)
7
(* License:  Apache 2.0                         *)
7
(* License:  Apache 2.0                         *)
8
(* This file contains:                          *)
8
(* This file contains:                          *)
9
(* - "OIDplus for DOS" program                  *)
9
(* - "OIDplus for DOS" program                  *)
10
(************************************************)
10
(************************************************)
11
 
11
 
12
(* IMPORTANT:                                                  *)
12
(* IMPORTANT:                                                  *)
13
(* When you compile this code with Turbo Pascal 7.01,          *)
13
(* When you compile this code with Turbo Pascal 7.01,          *)
14
(* it won't run on fast PCs (Runtime Error 200).               *)
14
(* it won't run on fast PCs (Runtime Error 200).               *)
15
(* The built EXE file needs to be patched.                     *)
15
(* The built EXE file needs to be patched.                     *)
16
(* The program "PatchCRT" by Kennedy Software                  *)
16
(* The program "PatchCRT" by Kennedy Software                  *)
17
(* WON'T work because it somehow breaks our "_Pause" function. *)
17
(* WON'T work because it somehow breaks our "_Pause" function. *)
18
(* Instead, use the tool "TPPATCH" by Andreas Bauer.           *)
18
(* Instead, use the tool "TPPATCH" by Andreas Bauer.           *)
19
 
19
 
20
uses
20
uses
21
  Dos, Crt, StrList, VtsFuncs, VtsCui, OidFile, OidUtils;
21
  Dos, Crt, StrList, VtsFuncs, VtsCui, OidFile, OidUtils;
22
 
22
 
23
const
23
const
24
  VERSIONINFO            = 'Revision: 2022-02-14';
24
  VERSIONINFO            = 'Revision: 2022-02-14';
25
  DEFAULT_STATUSBAR      = '(C)2020-2022 ViaThinkSoft. Licensed under the terms of the Apache 2.0 license.';
25
  DEFAULT_STATUSBAR      = '(C)2020-2022 ViaThinkSoft. Licensed under the terms of the Apache 2.0 license.';
26
  TITLEBAR_LEFT_TEXT     = 'OIDplus';
26
  TITLEBAR_LEFT_TEXT     = 'OIDplus';
27
  DISKIO_SOUND_DEBUGGING = false;
27
  DISKIO_SOUND_DEBUGGING = false;
28
  DISKIO_SOUND_DELAY     = 500;
28
  DISKIO_SOUND_DELAY     = 500;
29
  ASNEDIT_LINES          = 10;
29
  ASNEDIT_LINES          = 10;
30
  DESCEDIT_LINES         = 10;
30
  DESCEDIT_LINES         = 10;
31
  DESCEDIT_PADDING       = 3;
31
  DESCEDIT_PADDING       = 3;
32
  ACTIONMENU_SIZE        = 5;
32
  ACTIONMENU_SIZE        = 5;
33
  MAINMENU_WIDTH         = 15;
33
  MAINMENU_WIDTH         = 15;
34
  MAINMENU_HEIGHT        = 3;
34
  MAINMENU_HEIGHT        = 3;
35
  MAINMENU_ALLOW_ESC     = false;
35
  MAINMENU_ALLOW_ESC     = false;
36
  TREEVIEW_INDENT        = 0;
36
  TREEVIEW_INDENT        = 0;
37
  TREEVIEW_INCLUDE_DESC  = true;
37
  TREEVIEW_INCLUDE_DESC  = true;
38
  TREEVIEW_WIDTH         = 80;
38
  TREEVIEW_WIDTH         = 80;
39
 
39
 
40
procedure _WriteOidFile(filename: string; oid: POid);
40
procedure _WriteOidFile(filename: string; oid: POid);
41
begin
41
begin
42
  DrawStatusBar('Write file ' + filename + '...');
42
  DrawStatusBar('Write file ' + filename + '...');
43
  WriteOidFile(filename, oid);
43
  WriteOidFile(filename, oid);
44
 
44
 
45
  if DISKIO_SOUND_DEBUGGING then
45
  if DISKIO_SOUND_DEBUGGING then
46
  begin
46
  begin
47
    Sound(70);
47
    Sound(70);
48
    Delay(DISKIO_SOUND_DELAY - 10);
48
    Delay(DISKIO_SOUND_DELAY - 10);
49
    NoSound;
49
    NoSound;
50
    Delay(10);
50
    Delay(10);
51
  end;
51
  end;
52
 
52
 
53
  DrawStatusBar(DEFAULT_STATUSBAR);
53
  DrawStatusBar(DEFAULT_STATUSBAR);
54
end;
54
end;
55
 
55
 
56
procedure _ReadOidFile(filename: string; oid: POid);
56
procedure _ReadOidFile(filename: string; oid: POid);
57
begin
57
begin
58
  DrawStatusBar('Read file ' + filename + '...');
58
  DrawStatusBar('Read file ' + filename + '...');
59
  ReadOidFile(filename, oid);
59
  ReadOidFile(filename, oid);
60
 
60
 
61
  if DISKIO_SOUND_DEBUGGING then
61
  if DISKIO_SOUND_DEBUGGING then
62
  begin
62
  begin
63
    Sound(50);
63
    Sound(50);
64
    Delay(DISKIO_SOUND_DELAY - 10);
64
    Delay(DISKIO_SOUND_DELAY - 10);
65
    NoSound;
65
    NoSound;
66
    Delay(10);
66
    Delay(10);
67
  end;
67
  end;
68
 
68
 
69
  DrawStatusBar(DEFAULT_STATUSBAR);
69
  DrawStatusBar(DEFAULT_STATUSBAR);
70
end;
70
end;
71
 
71
 
72
procedure _Pause;
72
procedure _Pause;
73
var
73
var
74
  bakX, bakY: integer;
74
  bakX, bakY: integer;
75
begin
75
begin
76
  bakX := WhereX;
76
  bakX := WhereX;
77
  bakY := WhereY;
77
  bakY := WhereY;
78
  DrawStatusBar('Press any key to continue');
78
  DrawStatusBar('Press any key to continue');
79
  GoToXY(bakX, bakY);
79
  GoToXY(bakX, bakY);
80
  ReadKey;
80
  ReadKey;
81
  DrawStatusBar(DEFAULT_STATUSBAR);
81
  DrawStatusBar(DEFAULT_STATUSBAR);
82
end;
82
end;
83
 
83
 
84
function _ShowASNIds(childOID: POID): string;
84
function _ShowASNIds(childOID: POID): string;
85
var
85
var
86
  j, jmax: integer;
86
  j, jmax: integer;
87
  sTmp: string;
87
  sTmp: string;
88
begin
88
begin
89
  sTmp := '';
89
  sTmp := '';
90
  jmax := ListCount(childOID^.ASNIds)-1;
90
  jmax := ListCount(childOID^.ASNIds)-1;
91
  for j := 0 to jmax do
91
  for j := 0 to jmax do
92
  begin
92
  begin
93
    if j = 0 then sTmp := sTmp + ' (';
93
    if j = 0 then sTmp := sTmp + ' (';
94
    sTmp := sTmp + ListGetElement(childOID^.ASNIds, j);
94
    sTmp := sTmp + ListGetElement(childOID^.ASNIds, j);
95
    if j = jmax then
95
    if j = jmax then
96
      sTmp := sTmp + ')'
96
      sTmp := sTmp + ')'
97
    else
97
    else
98
      sTmp := sTmp + ', ';
98
      sTmp := sTmp + ', ';
99
  end;
99
  end;
100
  _ShowASNIds := sTmp;
100
  _ShowASNIds := sTmp;
101
end;
101
end;
102
 
102
 
103
function AsnAlreadyExisting(oid: POID; asnid: string): boolean;
103
function AsnAlreadyExisting(oid: POID; asnid: string): boolean;
104
begin
104
begin
105
  AsnAlreadyExisting := ListContains(oid^.AsnIds, asnid);
105
  AsnAlreadyExisting := ListContains(oid^.AsnIds, asnid);
106
end;
106
end;
107
 
107
 
108
function AsnEditor(oid: POID): boolean;
108
function AsnEditor(oid: POID): boolean;
109
var
109
var
110
  asnList: PStringList;
110
  asnList: PStringList;
111
  i: integer;
111
  i: integer;
112
  x, y, w, h: integer;
112
  x, y, w, h: integer;
113
  res: integer;
113
  res: integer;
114
  sInput: string;
114
  sInput: string;
115
  menuIdNew, menuIdSave, menuIdExit: integer;
115
  menuIdNew, menuIdSave, menuIdExit: integer;
116
begin
116
begin
117
  AsnEditor := false;
117
  AsnEditor := false;
118
 
118
 
119
  repeat
119
  repeat
120
    CreateList(asnList);
120
    CreateList(asnList);
121
 
121
 
122
    for i := 0 to ListCount(oid^.ASNIds)-1 do
122
    for i := 0 to ListCount(oid^.ASNIds)-1 do
123
    begin
123
    begin
124
      ListAppend(asnList, ListGetElement(oid^.ASNIDs, i));
124
      ListAppend(asnList, ListGetElement(oid^.ASNIDs, i));
125
    end;
125
    end;
126
    menuIdNew  := ListAppend(asnList, '<NEW>');
126
    menuIdNew  := ListAppend(asnList, '<NEW>');
127
    menuIdSave := ListAppend(asnList, '<SAVE>');
127
    menuIdSave := ListAppend(asnList, '<SAVE>');
128
    menuIdExit := ListAppend(asnList, '<CANCEL>');
128
    menuIdExit := ListAppend(asnList, '<CANCEL>');
129
 
129
 
130
    DrawStatusBar(DEFAULT_STATUSBAR);
130
    DrawStatusBar(DEFAULT_STATUSBAR);
131
    x := SINGLE_LINE_BOX_PADDING;
131
    x := SINGLE_LINE_BOX_PADDING;
132
    y := ScreenHeight div 2 - ASNEDIT_LINES div 2;
132
    y := ScreenHeight div 2 - ASNEDIT_LINES div 2;
133
    w := ScreenWidth - (SINGLE_LINE_BOX_PADDING-1)*2;
133
    w := ScreenWidth - (SINGLE_LINE_BOX_PADDING-1)*2;
134
    h := ASNEDIT_LINES;
134
    h := ASNEDIT_LINES;
135
    res := DrawSelectionList(x, y, w, h,
135
    res := DrawSelectionList(x, y, w, h,
136
                             asnList, true,
136
                             asnList, true,
137
                             'EDIT ASN.1 IDENTIFIERS',
137
                             'EDIT ASN.1 IDENTIFIERS',
138
                             2);
138
                             2);
139
    FreeList(asnList);
139
    FreeList(asnList);
140
 
140
 
141
    (* Change double-border to thin-border *)
141
    (* Change double-border to thin-border *)
142
    DrawThinBorder(x-1, y-1, w+2, h+2);
142
    DrawThinBorder(x-1, y-1, w+2, h+2);
143
    GoToXY(x+1, y-1);
143
    GoToXY(x+1, y-1);
144
    Write('EDIT ASN.1 IDENTIFIERS');
144
    Write('EDIT ASN.1 IDENTIFIERS');
145
 
145
 
146
    if res = -1 then
146
    if res = -1 then
147
    begin
147
    begin
148
      exit;
148
      exit;
149
    end
149
    end
150
    else if res = menuIdNew then
150
    else if res = menuIdNew then
151
    begin
151
    begin
152
      (* "NEW" item was selected *)
152
      (* "NEW" item was selected *)
153
      sInput := '';
153
      sInput := '';
154
      repeat
154
      repeat
155
        if QueryVal(sInput,
155
        if QueryVal(sInput,
156
                    SINGLE_LINE_BOX_PADDING_INNER,
156
                    SINGLE_LINE_BOX_PADDING_INNER,
157
                    ScreenHeight div 2,
157
                    ScreenHeight div 2,
158
                    ScreenWidth - (SINGLE_LINE_BOX_PADDING_INNER-1)*2,
158
                    ScreenWidth - (SINGLE_LINE_BOX_PADDING_INNER-1)*2,
159
                    1,
159
                    1,
160
                    'ADD SINGLE ASN.1 ID',
160
                    'ADD SINGLE ASN.1 ID',
161
                    2) then
161
                    2) then
162
        begin
162
        begin
163
          if sInput = '' then continue;
163
          if sInput = '' then continue;
164
          if not ASN1IDValid(sInput) then
164
          if not ASN1IDValid(sInput) then
165
          begin
165
          begin
166
            ShowMessage('Invalid ASN1.ID! (Require -, a..z, A..Z, 0..9, begin with a-z)', 'ERROR', true);
166
            ShowMessage('Invalid ASN1.ID! (Require -, a..z, A..Z, 0..9, begin with a-z)', 'ERROR', true);
167
            _Pause;
167
            _Pause;
168
          end
168
          end
169
          else if AsnAlreadyExisting(oid, sInput) then
169
          else if AsnAlreadyExisting(oid, sInput) then
170
          begin
170
          begin
171
            ShowMessage('ASN.1 identifier is already existing on this arc', 'ERROR', true);
171
            ShowMessage('ASN.1 identifier is already existing on this arc', 'ERROR', true);
172
            _Pause;
172
            _Pause;
173
          end
173
          end
174
          else
174
          else
175
          begin
175
          begin
176
            ListAppend(oid^.ASNIDs, sInput);
176
            ListAppend(oid^.ASNIDs, sInput);
177
            break;
177
            break;
178
          end;
178
          end;
179
        end
179
        end
180
        else break;
180
        else break;
181
      until false;
181
      until false;
182
    end
182
    end
183
    else if res = menuIdSave then
183
    else if res = menuIdSave then
184
    begin
184
    begin
185
      (* "SAVE" item was selected *)
185
      (* "SAVE" item was selected *)
186
      AsnEditor := true;
186
      AsnEditor := true;
187
      Exit;
187
      Exit;
188
    end
188
    end
189
    else if res = menuIdExit then
189
    else if res = menuIdExit then
190
    begin
190
    begin
191
      (* "CANCEL" item was selected *)
191
      (* "CANCEL" item was selected *)
192
      AsnEditor := false;
192
      AsnEditor := false;
193
      Exit;
193
      Exit;
194
    end
194
    end
195
    else
195
    else
196
    begin
196
    begin
197
      DrawStatusBar('Note: Remove the text to delete the ASN.1 identifier');
197
      DrawStatusBar('Note: Remove the text to delete the ASN.1 identifier');
198
      sInput := ListGetElement(oid^.ASNIDs, res);
198
      sInput := ListGetElement(oid^.ASNIDs, res);
199
      repeat
199
      repeat
200
        if QueryVal(sInput,
200
        if QueryVal(sInput,
201
                    SINGLE_LINE_BOX_PADDING_INNER,
201
                    SINGLE_LINE_BOX_PADDING_INNER,
202
                    ScreenHeight div 2,
202
                    ScreenHeight div 2,
203
                    ScreenWidth - (SINGLE_LINE_BOX_PADDING_INNER-1)*2,
203
                    ScreenWidth - (SINGLE_LINE_BOX_PADDING_INNER-1)*2,
204
                    1,
204
                    1,
205
                    'EDIT SINGLE ASN.1 ID',
205
                    'EDIT SINGLE ASN.1 ID',
206
                    2) then
206
                    2) then
207
        begin
207
        begin
208
          if sInput = '' then
208
          if sInput = '' then
209
          begin
209
          begin
210
            (* Empty input = Delete ASN.1 ID *)
210
            (* Empty input = Delete ASN.1 ID *)
211
            ListDeleteElementByIndex(oid^.ASNIDs, res);
211
            ListDeleteElementByIndex(oid^.ASNIDs, res);
212
            break;
212
            break;
213
          end
213
          end
214
          else if not ASN1IDValid(sInput) then
214
          else if not ASN1IDValid(sInput) then
215
          begin
215
          begin
216
            ShowMessage('Invalid ASN1.ID! (Require -, a..z, A..Z, 0..9, begin with a-z)', 'ERROR', true);
216
            ShowMessage('Invalid ASN1.ID! (Require -, a..z, A..Z, 0..9, begin with a-z)', 'ERROR', true);
217
            _Pause;
217
            _Pause;
218
          end
218
          end
219
          else if AsnAlreadyExisting(oid, sInput) and
219
          else if AsnAlreadyExisting(oid, sInput) and
220
              not (ListGetElement(oid^.ASNIDs, res) = sInput) then
220
              not (ListGetElement(oid^.ASNIDs, res) = sInput) then
221
          begin
221
          begin
222
            ShowMessage('ASN.1 identifier is already existing on this arc', 'ERROR', true);
222
            ShowMessage('ASN.1 identifier is already existing on this arc', 'ERROR', true);
223
            _Pause;
223
            _Pause;
224
          end
224
          end
225
          else
225
          else
226
          begin
226
          begin
227
            ListSetElement(oid^.ASNIDs, res, sInput);
227
            ListSetElement(oid^.ASNIDs, res, sInput);
228
            break;
228
            break;
229
          end;
229
          end;
230
        end
230
        end
231
        else break;
231
        else break;
232
      until false;
232
      until false;
233
    end;
233
    end;
234
  until false;
234
  until false;
235
end;
235
end;
236
 
236
 
237
function DescEditor(oid: POID): boolean;
237
function DescEditor(oid: POID): boolean;
238
var
238
var
239
  sInput: string;
239
  sInput: string;
240
begin
240
begin
241
  DescEditor := false;
241
  DescEditor := false;
242
 
242
 
243
  DrawStatusBar('Note: Press Ctrl+Return for a line-break.');
243
  DrawStatusBar('Note: Press Ctrl+Return for a line-break.');
244
  sInput := oid^.description;
244
  sInput := oid^.description;
245
  if QueryVal(sInput,
245
  if QueryVal(sInput,
246
              DESCEDIT_PADDING,
246
              DESCEDIT_PADDING,
247
              ScreenHeight div 2 - DESCEDIT_LINES div 2,
247
              ScreenHeight div 2 - DESCEDIT_LINES div 2,
248
              ScreenWidth - (DESCEDIT_PADDING-1)*2,
248
              ScreenWidth - (DESCEDIT_PADDING-1)*2,
249
              DESCEDIT_LINES,
249
              DESCEDIT_LINES,
250
              'EDIT DESCRIPTION',
250
              'EDIT DESCRIPTION',
251
              2) then
251
              2) then
252
  begin
252
  begin
253
    oid^.description := sInput;
253
    oid^.description := sInput;
254
    DescEditor := true; (* request caller to save <oid> *)
254
    DescEditor := true; (* request caller to save <oid> *)
255
  end;
255
  end;
256
end;
256
end;
257
 
257
 
258
function NextPossibleFileID: string;
258
function NextPossibleFileID: string;
259
var
259
var
260
  DirInfo: SearchRec;
260
  DirInfo: SearchRec;
261
  list: PStringList;
261
  list: PStringList;
262
  iId: LongInt;
262
  iId: LongInt;
263
  sId: string;
263
  sId: string;
264
begin
264
begin
265
  (* Put all found files into a list *)
265
  (* Put all found files into a list *)
266
  CreateList(list);
266
  CreateList(list);
267
  FindFirst('????????.OID', Archive, DirInfo);
267
  FindFirst('????????.OID', Archive, DirInfo);
268
  while DosError = 0 do
268
  while DosError = 0 do
269
  begin
269
  begin
270
    sId := Copy(DirInfo.Name, 1, 8);
270
    sId := Copy(DirInfo.Name, 1, 8);
271
    ListAppend(list, sId);
271
    ListAppend(list, sId);
272
    FindNext(DirInfo);
272
    FindNext(DirInfo);
273
  end;
273
  end;
274
 
274
 
275
  (* Search for the first non existing item in the list *)
275
  (* Search for the first non existing item in the list *)
276
  sId := '';
276
  sId := '';
277
  for iId := 0 to 99999999 do
277
  for iId := 0 to 99999999 do
278
  begin
278
  begin
279
    sId := ZeroPad(iId, 8);
279
    sId := ZeroPad(iId, 8);
280
    if not ListContains(list, sId) then break;
280
    if not ListContains(list, sId) then break;
281
  end;
281
  end;
282
  NextPossibleFileId := sId;
282
  NextPossibleFileId := sId;
283
  FreeList(list);
283
  FreeList(list);
284
end;
284
end;
285
 
285
 
286
function NumIdAlreadyExisting(parentOID: POID; sInput: string): boolean;
286
function NumIdAlreadyExisting(parentOID: POID; sInput: string): boolean;
287
var
287
var
288
  searchDotNotation: string;
288
  searchDotNotation: string;
289
  sTmp: string;
289
  sTmp: string;
290
  i: integer;
290
  i: integer;
291
begin
291
begin
292
  if parentOID^.DotNotation = '' then
292
  if parentOID^.DotNotation = '' then
293
    searchDotNotation := sInput
293
    searchDotNotation := sInput
294
  else
294
  else
295
    searchDotNotation := parentOID^.DotNotation + '.' + sInput;
295
    searchDotNotation := parentOID^.DotNotation + '.' + sInput;
296
  for i := 0 to ListCount(parentOID^.SubIds)-1 do
296
  for i := 0 to ListCount(parentOID^.SubIds)-1 do
297
  begin
297
  begin
298
    sTmp := ListGetElement(parentOID^.SubIds, i);
298
    sTmp := ListGetElement(parentOID^.SubIds, i);
299
    if DotNotationPart(sTmp) = searchDotNotation then
299
    if DotNotationPart(sTmp) = searchDotNotation then
300
    begin
300
    begin
301
      NumIdAlreadyExisting := true;
301
      NumIdAlreadyExisting := true;
302
      exit;
302
      exit;
303
    end;
303
    end;
304
  end;
304
  end;
305
  NumIdAlreadyExisting := false;
305
  NumIdAlreadyExisting := false;
306
end;
306
end;
307
 
307
 
308
function NumIdEditor(oid: POID; parentOID: POID): boolean;
308
function NumIdEditor(oid: POID; parentOID: POID): boolean;
309
var
309
var
310
  sInput: string;
310
  sInput: string;
311
begin
311
begin
312
  NumIdEditor := false;
312
  NumIdEditor := false;
313
  sInput := '';
313
  sInput := '';
314
 
314
 
315
  repeat
315
  repeat
316
    if QueryVal(sInput,
316
    if QueryVal(sInput,
317
                SINGLE_LINE_BOX_PADDING_INNER,
317
                SINGLE_LINE_BOX_PADDING_INNER,
318
                ScreenHeight div 2,
318
                ScreenHeight div 2,
319
                ScreenWidth - (SINGLE_LINE_BOX_PADDING_INNER-1)*2,
319
                ScreenWidth - (SINGLE_LINE_BOX_PADDING_INNER-1)*2,
320
                1,
320
                1,
321
                'ENTER NUMERIC ID',
321
                'ENTER NUMERIC ID',
322
                2) then
322
                2) then
323
    begin
323
    begin
324
      if sInput = '' then continue;
324
      if sInput = '' then continue;
325
      if not IsPositiveInteger(sInput) then
325
      if not IsPositiveInteger(sInput) then
326
      begin
326
      begin
327
        ShowMessage('Invalid numeric ID (must be a positive integer)', 'ERROR', true);
327
        ShowMessage('Invalid numeric ID (must be a positive integer)', 'ERROR', true);
328
        _Pause;
328
        _Pause;
329
      end
329
      end
330
      else if (parentOID^.DotNotation='') and (StrToInt(sInput) > 2) then
330
      else if (parentOID^.DotNotation='') and (StrToInt(sInput) > 2) then
331
      begin
331
      begin
332
        ShowMessage('Invalid numeric ID (root arc can only be 0, 1, or 2)', 'ERROR', true);
332
        ShowMessage('Invalid numeric ID (root arc can only be 0, 1, or 2)', 'ERROR', true);
333
        _Pause;
333
        _Pause;
334
      end
334
      end
335
      else if ((parentOID^.DotNotation='0') or (parentOID^.DotNotation='1')) and (StrToInt(sInput) > 39) then
335
      else if ((parentOID^.DotNotation='0') or (parentOID^.DotNotation='1')) and (StrToInt(sInput) > 39) then
336
      begin
336
      begin
337
        ShowMessage('Invalid numeric ID (root 0 and 1 must have sub-arc of 0..39)', 'ERROR', true);
337
        ShowMessage('Invalid numeric ID (root 0 and 1 must have sub-arc of 0..39)', 'ERROR', true);
338
        _Pause;
338
        _Pause;
339
      end
339
      end
340
      else if NumIdAlreadyExisting(parentOID, sInput) then
340
      else if NumIdAlreadyExisting(parentOID, sInput) then
341
      begin
341
      begin
342
        ShowMessage('This numeric ID is already used in this arc', 'ERROR', true);
342
        ShowMessage('This numeric ID is already used in this arc', 'ERROR', true);
343
        _Pause;
343
        _Pause;
344
      end
344
      end
345
      else
345
      else
346
      begin
346
      begin
347
        if parentOID^.DotNotation = '' then
347
        if parentOID^.DotNotation = '' then
348
          oid^.DotNotation := sInput
348
          oid^.DotNotation := sInput
349
        else
349
        else
350
          oid^.DotNotation := parentOID^.DotNotation + '.' + sInput;
350
          oid^.DotNotation := parentOID^.DotNotation + '.' + sInput;
351
        NumIdEditor := true; (* request caller to save <oid> *)
351
        NumIdEditor := true; (* request caller to save <oid> *)
352
        Exit;
352
        Exit;
353
      end;
353
      end;
354
    end
354
    end
355
    else
355
    else
356
    begin
356
    begin
357
      Exit;
357
      Exit;
358
    end;
358
    end;
359
  until false;
359
  until false;
360
end;
360
end;
361
 
361
 
362
function NewOidEditor(oid: POID): boolean;
362
function NewOidEditor(oid: POID): boolean;
363
var
363
var
364
  newfilename: string;
364
  newfilename: string;
365
  newOID: POID;
365
  newOID: POID;
366
begin
366
begin
367
  NewOidEditor := false;
367
  NewOidEditor := false;
368
 
368
 
369
  CreateOidDef(newOID);
369
  CreateOidDef(newOID);
370
  newOID^.FileId := NextPossibleFileID;
370
  newOID^.FileId := NextPossibleFileID;
371
  newOID^.Parent := oid^.FileId + oid^.DotNotation;
371
  newOID^.Parent := oid^.FileId + oid^.DotNotation;
372
  if NumIdEditor(newOID, oid) and
372
  if NumIdEditor(newOID, oid) and
373
     AsnEditor(newOID) and
373
     AsnEditor(newOID) and
374
     DescEditor(newOID) then
374
     DescEditor(newOID) then
375
  begin
375
  begin
376
    newfilename := newOID^.FileId + '.OID';
376
    newfilename := newOID^.FileId + '.OID';
377
    _WriteOidFile(newfilename, newOID);
377
    _WriteOidFile(newfilename, newOID);
378
 
378
 
379
    (* Add link to original file and enable the saving of it *)
379
    (* Add link to original file and enable the saving of it *)
380
    ListAppend(oid^.SubIds, newOID^.FileId + newOID^.DotNotation);
380
    ListAppend(oid^.SubIds, newOID^.FileId + newOID^.DotNotation);
381
    NewOidEditor := true; (* request caller to save <oid> *)
381
    NewOidEditor := true; (* request caller to save <oid> *)
382
  end;
382
  end;
383
  FreeOidDef(newOID);
383
  FreeOidDef(newOID);
384
end;
384
end;
385
 
385
 
386
procedure DeleteChildrenRecursive(oid: POID);
386
procedure DeleteChildrenRecursive(oid: POID);
387
var
387
var
388
  i: integer;
388
  i: integer;
389
  childOID: POID;
389
  childOID: POID;
390
  filenameChild: string;
390
  filenameChild: string;
391
begin
391
begin
392
  for i := 0 to ListCount(oid^.SubIds)-1 do
392
  for i := 0 to ListCount(oid^.SubIds)-1 do
393
  begin
393
  begin
394
    filenameChild := FileIdPart(ListGetElement(oid^.SubIds, i)) + '.OID';
394
    filenameChild := FileIdPart(ListGetElement(oid^.SubIds, i)) + '.OID';
395
    if FileExists(filenameChild) then
395
    if FileExists(filenameChild) then
396
    begin
396
    begin
397
      CreateOidDef(childOID);
397
      CreateOidDef(childOID);
398
      _ReadOidFile(filenameChild, childOID);
398
      _ReadOidFile(filenameChild, childOID);
399
      DeleteChildrenRecursive(childOID);
399
      DeleteChildrenRecursive(childOID);
400
      FreeOidDef(childOID);
400
      FreeOidDef(childOID);
401
      DeleteFile(filenameChild);
401
      DeleteFile(filenameChild);
402
    end;
402
    end;
403
  end;
403
  end;
404
  ListClear(oid^.SubIds);
404
  ListClear(oid^.SubIds);
405
end;
405
end;
406
 
406
 
407
procedure DeleteOidRecursive(selfOID: POID);
407
procedure DeleteOidRecursive(selfOID: POID);
408
var
408
var
409
  i: integer;
409
  i: integer;
410
  parentOID: POID;
410
  parentOID: POID;
411
  filenameSelf, filenameParent: string;
411
  filenameSelf, filenameParent: string;
412
begin
412
begin
413
  (* Remove all children and their files recursively *)
413
  (* Remove all children and their files recursively *)
414
  DeleteChildrenRecursive(selfOID);
414
  DeleteChildrenRecursive(selfOID);
415
 
415
 
416
  (* Remove forward reference in parent OID *)
416
  (* Remove forward reference in parent OID *)
417
  filenameParent := FileIdPart(selfOID^.Parent) + '.OID';
417
  filenameParent := FileIdPart(selfOID^.Parent) + '.OID';
418
  if FileExists(filenameParent) then
418
  if FileExists(filenameParent) then
419
  begin
419
  begin
420
    CreateOidDef(parentOID);
420
    CreateOidDef(parentOID);
421
    _ReadOidFile(filenameParent, parentOID);
421
    _ReadOidFile(filenameParent, parentOID);
422
    if ListDeleteElementByValue(parentOID^.SubIds, selfOID^.FileId + selfOID^.DotNotation) then
422
    if ListDeleteElementByValue(parentOID^.SubIds, selfOID^.FileId + selfOID^.DotNotation) then
423
    begin
423
    begin
424
      _WriteOidFile(filenameParent, parentOID);
424
      _WriteOidFile(filenameParent, parentOID);
425
    end;
425
    end;
426
    FreeOidDef(parentOID);
426
    FreeOidDef(parentOID);
427
  end;
427
  end;
428
 
428
 
429
  (* Delete own file *)
429
  (* Delete own file *)
430
  filenameSelf := selfOID^.FileId + '.OID';
430
  filenameSelf := selfOID^.FileId + '.OID';
431
  if FileExists(filenameSelf) then
431
  if FileExists(filenameSelf) then
432
  begin
432
  begin
433
    DeleteFile(filenameSelf);
433
    DeleteFile(filenameSelf);
434
  end;
434
  end;
435
end;
435
end;
436
 
436
 
437
function _DeleteConfirmation: boolean;
437
function _DeleteConfirmation: boolean;
438
var
438
var
439
  sc: Char;
439
  sc: Char;
440
begin
440
begin
441
  repeat
441
  repeat
442
    ShowMessage('Are you sure you want to delete this OID? (Y/N)', 'DELETE OID', true);
442
    ShowMessage('Are you sure you want to delete this OID? (Y/N)', 'DELETE OID', true);
443
    DrawStatusBar('Y=Yes, N=No');
443
    DrawStatusBar('Y=Yes, N=No');
444
 
444
 
445
    sc := ReadKey;
445
    sc := ReadKey;
446
    if sc = #0 then
446
    if sc = #0 then
447
    begin
447
    begin
448
      (* Extended key. Nothing we care about. *)
448
      (* Extended key. Nothing we care about. *)
449
      ReadKey;
449
      ReadKey;
450
      continue;
450
      continue;
451
    end;
451
    end;
452
 
452
 
453
    if UpCase(sc) = 'Y' then
453
    if UpCase(sc) = 'Y' then
454
    begin
454
    begin
455
      _DeleteConfirmation := true;
455
      _DeleteConfirmation := true;
456
      break;
456
      break;
457
    end
457
    end
458
    else if UpCase(sc) = 'N' then
458
    else if UpCase(sc) = 'N' then
459
    begin
459
    begin
460
      _DeleteConfirmation := false;
460
      _DeleteConfirmation := false;
461
      break;
461
      break;
462
    end;
462
    end;
463
  until false;
463
  until false;
464
end;
464
end;
465
 
465
 
466
procedure _DrawOidTitleBar(filename: string; oid: POID);
466
procedure _DrawOidTitleBar(filename: string; oid: POID);
467
begin
467
begin
468
  if oid^.DotNotation = '' then
468
  if oid^.DotNotation = '' then
469
    DrawTitleBar('OID ROOT', TITLEBAR_LEFT_TEXT, filename)
469
    DrawTitleBar('OID ROOT', TITLEBAR_LEFT_TEXT, filename)
470
  else
470
  else
471
    DrawTitleBar('OID ' + oid^.DotNotation, TITLEBAR_LEFT_TEXT, filename);
471
    DrawTitleBar('OID ' + oid^.DotNotation, TITLEBAR_LEFT_TEXT, filename);
472
end;
472
end;
473
 
473
 
474
procedure DisplayOIDFile(filename: string);
474
procedure DisplayOIDFile(filename: string);
475
var
475
var
476
  isRoot: boolean;
476
  isRoot: boolean;
477
  oid, tmpOID: POID;
477
  oid, tmpOID: POID;
478
  i, menuX, menuY: integer;
478
  i, menuX, menuY: integer;
479
  linesLeft, linesRequired: integer;
479
  linesLeft, linesRequired: integer;
480
  sTmp, subfile: string;
480
  sTmp, subfile: string;
481
  subsel, subfiles: PStringList;
481
  subsel, subfiles: PStringList;
482
  subselres: integer;
482
  subselres: integer;
483
  exitRequest: boolean;
483
  exitRequest: boolean;
484
  menuIdExit, menuIdAsnEdit, menuIdDescEdit, menuIdAdd, menuIdDelete: integer;
484
  menuIdExit, menuIdAsnEdit, menuIdDescEdit, menuIdAdd, menuIdDelete: integer;
485
begin
485
begin
486
  exitRequest := false;
486
  exitRequest := false;
487
  repeat
487
  repeat
488
    if not FileExists(filename) then
488
    if not FileExists(filename) then
489
    begin
489
    begin
490
      ShowMessage('File ' + filename + ' not found', 'ERROR', true);
490
      ShowMessage('File ' + filename + ' not found', 'ERROR', true);
491
      _Pause;
491
      _Pause;
492
      exit;
492
      exit;
493
    end;
493
    end;
494
 
494
 
495
    CreateOidDef(oid);
495
    CreateOidDef(oid);
496
    _ReadOidFile(filename, oid);
496
    _ReadOidFile(filename, oid);
497
 
497
 
498
    (* Print OID information *)
498
    (* Print OID information *)
499
 
499
 
500
    ClrScr;
500
    ClrScr;
501
    _DrawOidTitleBar(filename, oid);
501
    _DrawOidTitleBar(filename, oid);
502
    DrawStatusBar(DEFAULT_STATUSBAR);
502
    DrawStatusBar(DEFAULT_STATUSBAR);
503
    GotoXY(1,2);
503
    GotoXY(1,2);
504
 
504
 
505
    if oid^.DotNotation <> '' then
505
    if oid^.DotNotation <> '' then
506
    begin
506
    begin
507
      WriteLn('Dot-Notation:');
507
      WriteLn('Dot-Notation:');
508
      WriteLn(oid^.DotNotation);
508
      WriteLn(oid^.DotNotation);
509
      WriteLn('');
509
      WriteLn('');
510
    end;
510
    end;
511
 
511
 
512
    if Trim(oid^.Description) <> '' then
512
    if Trim(oid^.Description) <> '' then
513
    begin
513
    begin
514
      WriteLn('Description:');
514
      WriteLn('Description:');
515
      WriteLn(oid^.Description);
515
      WriteLn(oid^.Description);
516
      WriteLn('');
516
      WriteLn('');
517
    end;
517
    end;
518
 
518
 
519
    menuX := WhereX + 1;
519
    menuX := WhereX + 1;
520
    menuY := ScreenHeight - ACTIONMENU_SIZE - 1;
520
    menuY := ScreenHeight - ACTIONMENU_SIZE - 1;
521
 
521
 
522
    if ListCount(oid^.ASNIDs) > 0 then
522
    if ListCount(oid^.ASNIDs) > 0 then
523
    begin
523
    begin
524
      linesLeft := menuY - WhereY - 1;
524
      linesLeft := menuY - WhereY - 1;
525
      linesRequired := 1 + ListCount(oid^.ASNIds);
525
      linesRequired := 1 + ListCount(oid^.ASNIds);
526
 
526
 
527
      if LinesLeft < LinesRequired then
527
      if LinesLeft < LinesRequired then
528
      begin
528
      begin
529
        (* Compact display of ASN.1 identifiers *)
529
        (* Compact display of ASN.1 identifiers *)
530
        Write('ASN.1-Identifiers: ');
530
        Write('ASN.1-Identifiers: ');
531
        for i := 0 to ListCount(oid^.ASNIds)-1 do
531
        for i := 0 to ListCount(oid^.ASNIds)-1 do
532
        begin
532
        begin
533
          if i > 0 then Write(', ');
533
          if i > 0 then Write(', ');
534
          Write(ListGetElement(oid^.ASNIds, i));
534
          Write(ListGetElement(oid^.ASNIds, i));
535
        end;
535
        end;
536
        WriteLn('');
536
        WriteLn('');
537
      end
537
      end
538
      else
538
      else
539
      begin
539
      begin
540
        (* Long display of ASN.1 identifiers *)
540
        (* Long display of ASN.1 identifiers *)
541
        WriteLn('ASN.1-Identifiers:');
541
        WriteLn('ASN.1-Identifiers:');
542
        for i := 0 to ListCount(oid^.ASNIds)-1 do
542
        for i := 0 to ListCount(oid^.ASNIds)-1 do
543
        begin
543
        begin
544
          WriteLn('- '+ListGetElement(oid^.ASNIds, i));
544
          WriteLn('- '+ListGetElement(oid^.ASNIds, i));
545
        end;
545
        end;
546
        WriteLn('');
546
        WriteLn('');
547
      end;
547
      end;
548
    end;
548
    end;
549
 
549
 
550
    (* Now prepare the menu entries *)
550
    (* Now prepare the menu entries *)
551
 
551
 
552
    CreateList(subsel);   (* Contains the human readable OID name *)
552
    CreateList(subsel);   (* Contains the human readable OID name *)
553
    CreateList(subfiles); (* Contains the file name               *)
553
    CreateList(subfiles); (* Contains the file name               *)
554
 
554
 
555
    if oid^.Parent = '' then
555
    if oid^.Parent = '' then
556
    begin
556
    begin
557
      isRoot := true;
557
      isRoot := true;
558
    end
558
    end
559
    else
559
    else
560
    begin
560
    begin
561
      isRoot := DotNotationPart(oid^.Parent) = oid^.DotNotation;
561
      isRoot := DotNotationPart(oid^.Parent) = oid^.DotNotation;
562
    end;
562
    end;
563
 
563
 
564
    if (oid^.Parent <> '') and not isRoot then
564
    if (oid^.Parent <> '') and not isRoot then
565
    begin
565
    begin
566
      sTmp := oid^.Parent;
566
      sTmp := oid^.Parent;
567
      subfile := FileIdPart(sTmp) + '.OID';
567
      subfile := FileIdPart(sTmp) + '.OID';
568
      if FileExists(subfile) then
568
      if FileExists(subfile) then
569
      begin
569
      begin
570
        CreateOidDef(tmpOID);
570
        CreateOidDef(tmpOID);
571
        _ReadOidFile(subfile, tmpOID);
571
        _ReadOidFile(subfile, tmpOID);
572
        ListAppend(subsel, 'Go to parent ' + DotNotationPart(sTmp) + _ShowASNIds(tmpOID));
572
        ListAppend(subsel, 'Go to parent ' + DotNotationPart(sTmp) + _ShowASNIds(tmpOID));
573
        FreeOidDef(tmpOID);
573
        FreeOidDef(tmpOID);
574
      end
574
      end
575
      else
575
      else
576
      begin
576
      begin
577
        ListAppend(subsel, 'Go to parent ' + DotNotationPart(sTmp) + ' (FILE NOT FOUND)');
577
        ListAppend(subsel, 'Go to parent ' + DotNotationPart(sTmp) + ' (FILE NOT FOUND)');
578
      end;
578
      end;
579
      ListAppend(subfiles, subfile);
579
      ListAppend(subfiles, subfile);
580
    end;
580
    end;
581
 
581
 
582
    if isRoot then
582
    if isRoot then
583
    begin
583
    begin
584
      menuIdExit := ListAppend(subsel, 'Back to main menu');
584
      menuIdExit := ListAppend(subsel, 'Back to main menu');
585
      ListAppend(subfiles, '');
585
      ListAppend(subfiles, '');
586
    end
586
    end
587
    else menuIdExit := -99;
587
    else menuIdExit := -99;
588
 
588
 
589
    for i := 0 to ListCount(oid^.SubIds)-1 do
589
    for i := 0 to ListCount(oid^.SubIds)-1 do
590
    begin
590
    begin
591
      sTmp := ListGetElement(oid^.SubIds, i);
591
      sTmp := ListGetElement(oid^.SubIds, i);
592
      subfile := FileIdPart(sTmp) + '.OID';
592
      subfile := FileIdPart(sTmp) + '.OID';
593
      if FileExists(subfile) then
593
      if FileExists(subfile) then
594
      begin
594
      begin
595
        CreateOidDef(tmpOID);
595
        CreateOidDef(tmpOID);
596
        _ReadOidFile(subfile, tmpOID);
596
        _ReadOidFile(subfile, tmpOID);
597
        ListAppend(subsel, 'Go to child  ' + DotNotationPart(sTmp) + _ShowASNIds(tmpOID));
597
        ListAppend(subsel, 'Go to child  ' + DotNotationPart(sTmp) + _ShowASNIds(tmpOID));
598
        FreeOidDef(tmpOID);
598
        FreeOidDef(tmpOID);
599
      end
599
      end
600
      else
600
      else
601
      begin
601
      begin
602
        ListAppend(subsel, 'Go to child  ' + DotNotationPart(sTmp) + ' (FILE NOT FOUND)');
602
        ListAppend(subsel, 'Go to child  ' + DotNotationPart(sTmp) + ' (FILE NOT FOUND)');
603
      end;
603
      end;
604
      ListAppend(subfiles, subfile);
604
      ListAppend(subfiles, subfile);
605
    end;
605
    end;
606
 
606
 
607
    if oid^.DotNotation <> '' then
607
    if oid^.DotNotation <> '' then
608
    begin
608
    begin
609
      menuIdAsnEdit := ListAppend(subsel, 'Edit ASN.1 identifiers');
609
      menuIdAsnEdit := ListAppend(subsel, 'Edit ASN.1 identifiers');
610
      ListAppend(subfiles, '');
610
      ListAppend(subfiles, '');
611
    end
611
    end
612
    else menuIdAsnEdit := -99;
612
    else menuIdAsnEdit := -99;
613
 
613
 
614
    menuIdDescEdit := ListAppend(subsel, 'Edit description');
614
    menuIdDescEdit := ListAppend(subsel, 'Edit description');
615
    ListAppend(subfiles, '');
615
    ListAppend(subfiles, '');
616
 
616
 
617
    menuIdAdd := ListAppend(subsel, 'Add child');
617
    menuIdAdd := ListAppend(subsel, 'Add child');
618
    ListAppend(subfiles, '');
618
    ListAppend(subfiles, '');
619
 
619
 
620
    if not isRoot then
620
    if not isRoot then
621
    begin
621
    begin
622
      menuIdDelete := ListAppend(subsel, 'Delete OID');
622
      menuIdDelete := ListAppend(subsel, 'Delete OID');
623
      ListAppend(subfiles, '');
623
      ListAppend(subfiles, '');
624
    end
624
    end
625
    else menuIdDelete := -99;
625
    else menuIdDelete := -99;
626
 
626
 
627
    (* Show menu *)
627
    (* Show menu *)
628
 
628
 
629
    subselres := DrawSelectionList(menuX, menuY,
629
    subselres := DrawSelectionList(menuX, menuY,
630
                                   ScreenWidth-2,
630
                                   ScreenWidth-2,
631
                                   ACTIONMENU_SIZE,
631
                                   ACTIONMENU_SIZE,
632
                                   subsel,
632
                                   subsel,
633
                                   true,
633
                                   true,
634
                                   'SELECT ACTION',
634
                                   'SELECT ACTION',
635
                                   1);
635
                                   1);
636
 
636
 
637
    (* Process user selection *)
637
    (* Process user selection *)
638
 
638
 
639
    if subselres = -1 then
639
    if subselres = -1 then
640
    begin
640
    begin
641
      exitRequest := true;
641
      exitRequest := true;
642
    end
642
    end
643
    else if subselres = menuIdAsnEdit then
643
    else if subselres = menuIdAsnEdit then
644
    begin
644
    begin
645
      if AsnEditor(oid) then
645
      if AsnEditor(oid) then
646
        _WriteOidFile(filename, oid);
646
        _WriteOidFile(filename, oid);
647
    end
647
    end
648
    else if subselres = menuIdDescEdit then
648
    else if subselres = menuIdDescEdit then
649
    begin
649
    begin
650
      if DescEditor(oid) then
650
      if DescEditor(oid) then
651
        _WriteOidFile(filename, oid);
651
        _WriteOidFile(filename, oid);
652
    end
652
    end
653
    else if subselres = menuIdAdd then
653
    else if subselres = menuIdAdd then
654
    begin
654
    begin
655
      if NewOidEditor(oid) then
655
      if NewOidEditor(oid) then
656
        _WriteOidFile(filename, oid);
656
        _WriteOidFile(filename, oid);
657
    end
657
    end
658
    else if subselres = menuIdDelete then
658
    else if subselres = menuIdDelete then
659
    begin
659
    begin
660
      if _DeleteConfirmation then
660
      if _DeleteConfirmation then
661
      begin
661
      begin
662
        sTmp := FileIdPart(oid^.Parent) + '.OID';
662
        sTmp := FileIdPart(oid^.Parent) + '.OID';
663
        DeleteOidRecursive(oid);
663
        DeleteOidRecursive(oid);
664
        if FileExists(sTmp) then
664
        if FileExists(sTmp) then
665
        begin
665
        begin
666
          filename := sTmp;
666
          filename := sTmp;
667
        end
667
        end
668
        else
668
        else
669
        begin
669
        begin
670
          ShowMessage('Parent file ' + filename + ' not found', 'ERROR', true);
670
          ShowMessage('Parent file ' + filename + ' not found', 'ERROR', true);
671
          _Pause;
671
          _Pause;
672
          exitRequest := true;
672
          exitRequest := true;
673
        end;
673
        end;
674
      end;
674
      end;
675
    end
675
    end
676
    else if subselres = menuIdExit then
676
    else if subselres = menuIdExit then
677
    begin
677
    begin
678
      exitRequest := true;
678
      exitRequest := true;
679
    end
679
    end
680
    else
680
    else
681
    begin
681
    begin
682
      (* Normal OID *)
682
      (* Normal OID *)
683
      sTmp := ListGetElement(subfiles, subselres);
683
      sTmp := ListGetElement(subfiles, subselres);
684
      if FileExists(sTmp) then
684
      if FileExists(sTmp) then
685
      begin
685
      begin
686
        filename := sTmp;
686
        filename := sTmp;
687
      end
687
      end
688
      else
688
      else
689
      begin
689
      begin
690
        ShowMessage('File ' + filename + ' not found', 'ERROR', true);
690
        ShowMessage('File ' + filename + ' not found', 'ERROR', true);
691
        _Pause;
691
        _Pause;
692
      end;
692
      end;
693
    end;
693
    end;
694
    FreeList(subsel);
694
    FreeList(subsel);
695
    FreeList(subfiles);
695
    FreeList(subfiles);
696
 
696
 
697
    FreeOidDef(oid);
697
    FreeOidDef(oid);
698
  until exitRequest;
698
  until exitRequest;
699
end;
699
end;
700
 
700
 
701
procedure CreateInitOIDFile(filename: string);
701
procedure CreateRootOIDFile(filename: string);
702
var
702
var
703
  oid: POID;
703
  oid: POID;
704
begin
704
begin
705
  CreateOidDef(oid);
705
  CreateOidDef(oid);
706
  oid^.Description := 'This is the root of the OID tree.' +#13#10 +
706
  oid^.Description := 'This is the root of the OID tree.' +#13#10 +
707
                      #13#10 +
707
                      #13#10 +
708
                      'Valid subsequent arcs are per definition:' + #13#10 +
708
                      'Valid subsequent arcs are per definition:' + #13#10 +
709
                      '- 0 (itu-t)' + #13#10 +
709
                      '- 0 (itu-t)' + #13#10 +
710
                      '- 1 (iso)' + #13#10 +
710
                      '- 1 (iso)' + #13#10 +
711
                      '- 2 (joint-iso-itu-t)';
711
                      '- 2 (joint-iso-itu-t)';
712
  oid^.FileId      := ZeroPad(0, 8);
712
  oid^.FileId      := ZeroPad(0, 8);
713
  oid^.DotNotation := '';
713
  oid^.DotNotation := '';
714
  oid^.Parent      := ZeroPad(0, 8);
714
  oid^.Parent      := ZeroPad(0, 8);
715
  _WriteOidFile(filename, oid);
715
  _WriteOidFile(filename, oid);
716
  FreeOidDef(oid);
716
  FreeOidDef(oid);
717
end;
717
end;
718
 
718
 
719
function _GetInitFile: string;
719
function _GetRootFile(ShowErrorMessage: boolean): string;
720
var
720
var
721
  initFile: string;
721
  rootFile: string;
722
begin
722
begin
723
  initFile := ZeroPad(0, 8) + '.OID';
723
  rootFile := ZeroPad(0, 8) + '.OID';
724
  if not FileExists(initFile) then
724
  if not FileExists(rootFile) then
725
  begin
725
  begin
-
 
726
    {$I-}
726
    CreateInitOIDFile(initFile);
727
    CreateRootOIDFile(rootFile);
-
 
728
    {$I+}
-
 
729
  end;
-
 
730
  if not FileExists(rootFile) then
-
 
731
  begin
-
 
732
    _GetRootFile := '';
-
 
733
    if ShowErrorMessage then
-
 
734
    begin
-
 
735
      ShowMessage('Cannot create ' + rootfile + '! Is disk read-only?', 'ERROR', true);
-
 
736
      _Pause;
-
 
737
    end;
-
 
738
  end
-
 
739
  else
-
 
740
  begin
-
 
741
    _GetRootFile := rootFile;
727
  end;
742
  end;
728
  _GetInitFile := initFile;
-
 
729
end;
743
end;
730
 
744
 
731
procedure OP_ManageOIDs;
745
procedure OP_ManageOIDs;
-
 
746
var
-
 
747
  rootfile: string;
732
begin
748
begin
733
  ClrScr;
749
  ClrScr;
734
  DrawTitleBar('Manage Object Identifiers', TITLEBAR_LEFT_TEXT, '');
750
  DrawTitleBar('Manage Object Identifiers', TITLEBAR_LEFT_TEXT, '');
735
  DrawStatusBar('Loading data... please wait...');
751
  DrawStatusBar('Loading data... please wait...');
736
 
752
 
-
 
753
  (* This will try creating a new root file if it does not exist *)
-
 
754
  rootfile := _GetRootFile(true);
-
 
755
  if rootfile = '' then Exit;
-
 
756
 
737
  DisplayOIDFile(_GetInitFile);
757
  DisplayOIDFile(rootfile);
738
end;
758
end;
739
 
759
 
740
procedure OP_ManageRAs;
760
procedure OP_ManageRAs;
741
begin
761
begin
742
  ClrScr;
762
  ClrScr;
743
  DrawTitleBar('Manage Registration Authorities', TITLEBAR_LEFT_TEXT, '');
763
  DrawTitleBar('Manage Registration Authorities', TITLEBAR_LEFT_TEXT, '');
744
  DrawStatusBar('');
764
  DrawStatusBar('');
745
 
765
 
746
  (* TODO: Implement "Manage RAs" feature *)
766
  (* TODO: Implement "Manage RAs" feature *)
747
end;
767
end;
748
 
768
 
749
procedure OP_ReturnToMSDOS;
769
procedure OP_ReturnToMSDOS;
750
begin
770
begin
751
  ClrScr;
771
  ClrScr;
752
  WriteLn('Thank you for using OIDplus for DOS.');
772
  WriteLn('Thank you for using OIDplus for DOS.');
753
  WRiteLn('');
773
  WRiteLn('');
754
end;
774
end;
755
 
775
 
756
function _GetTreeViewLine(oid: POID; indent: integer): string;
776
function _GetTreeViewLine(oid: POID; indent: integer): string;
757
var
777
var
758
  i: integer;
778
  i: integer;
759
  sTmp: string;
779
  sTmp: string;
760
begin
780
begin
761
  (* Build line *)
781
  (* Build line *)
762
  sTmp := RepeatStr(' ', indent*TREEVIEW_INDENT);
782
  sTmp := RepeatStr(' ', indent*TREEVIEW_INDENT);
763
  if oid^.DotNotation = '' then
783
  if oid^.DotNotation = '' then
764
    sTmp := sTmp + 'Object Identifiers'
784
    sTmp := sTmp + 'Object Identifiers'
765
  else
785
  else
766
    sTmp := sTmp + oid^.DotNotation;
786
    sTmp := sTmp + oid^.DotNotation;
767
  sTmp := sTmp + _ShowAsnIds(oid);
787
  sTmp := sTmp + _ShowAsnIds(oid);
768
  if TREEVIEW_INCLUDE_DESC then
788
  if TREEVIEW_INCLUDE_DESC then
769
  begin
789
  begin
770
    if Trim(oid^.Description) <> '' then
790
    if Trim(oid^.Description) <> '' then
771
    begin
791
    begin
772
      sTmp := sTmp + ': ' + oid^.Description;
792
      sTmp := sTmp + ': ' + oid^.Description;
773
    end;
793
    end;
774
  end;
794
  end;
775
  for i := 1 to Length(sTmp) do
795
  for i := 1 to Length(sTmp) do
776
  begin
796
  begin
777
    if (sTmp[i]=#13) or (sTmp[i]=#10) then sTmp[i] := ' ';
797
    if (sTmp[i]=#13) or (sTmp[i]=#10) then sTmp[i] := ' ';
778
  end;
798
  end;
779
  if Length(sTmp) > TREEVIEW_WIDTH then
799
  if Length(sTmp) > TREEVIEW_WIDTH then
780
  begin
800
  begin
781
    sTmp := Copy(sTmp, 1, TREEVIEW_WIDTH-3) + '...';
801
    sTmp := Copy(sTmp, 1, TREEVIEW_WIDTH-3) + '...';
782
  end;
802
  end;
783
  _GetTreeViewLine := sTmp;
803
  _GetTreeViewLine := sTmp;
784
end;
804
end;
785
 
805
 
786
procedure _RecTreeExport(oid: POID; var F: Text; indent: integer);
806
procedure _RecTreeExport(oid: POID; var F: Text; indent: integer);
787
var
807
var
788
  i: integer;
808
  i: integer;
789
  sTmp: string;
809
  sTmp: string;
790
  suboid: POID;
810
  suboid: POID;
791
  childFilename: string;
811
  childFilename: string;
792
begin
812
begin
793
  sTmp := _GetTreeViewLine(oid, indent);
813
  sTmp := _GetTreeViewLine(oid, indent);
794
  sTmp := TrimLineToWidth(sTmp, TREEVIEW_WIDTH);
814
  sTmp := TrimLineToWidth(sTmp, TREEVIEW_WIDTH);
795
  WriteLn(F, sTmp);
815
  WriteLn(F, sTmp);
796
 
816
 
797
  (* Recursively call children *)
817
  (* Recursively call children *)
798
  for i := 0 to ListCount(oid^.SubIds)-1 do
818
  for i := 0 to ListCount(oid^.SubIds)-1 do
799
  begin
819
  begin
800
    sTmp := ListGetElement(oid^.SubIds, i);
820
    sTmp := ListGetElement(oid^.SubIds, i);
801
    CreateOidDef(suboid);
821
    CreateOidDef(suboid);
802
    childFilename := FileIdPart(sTmp) + '.OID';
822
    childFilename := FileIdPart(sTmp) + '.OID';
803
    if FileExists(childFilename) then
823
    if FileExists(childFilename) then
804
    begin
824
    begin
805
      _ReadOidFile(childFilename, suboid);
825
      _ReadOidFile(childFilename, suboid);
806
      _RecTreeExport(suboid, F, indent+1);
826
      _RecTreeExport(suboid, F, indent+1);
807
      FreeOidDef(suboid);
827
      FreeOidDef(suboid);
808
    end
828
    end
809
    else
829
    else
810
    begin
830
    begin
811
      sTmp := 'ERROR: FILE ' + childFilename + ' CONTAINING CHILD OID ' + DotNotationPart(sTmp) + ' WAS NOT FOUND!';
831
      sTmp := 'ERROR: FILE ' + childFilename + ' CONTAINING CHILD OID ' + DotNotationPart(sTmp) + ' WAS NOT FOUND!';
812
      sTmp := TrimLineToWidth(sTmp, TREEVIEW_WIDTH);
832
      sTmp := TrimLineToWidth(sTmp, TREEVIEW_WIDTH);
813
      WriteLn(F, sTmp);
833
      WriteLn(F, sTmp);
814
    end;
834
    end;
815
  end;
835
  end;
816
end;
836
end;
817
 
837
 
818
procedure OP_TreeView;
838
procedure OP_TreeView;
819
var
839
var
820
  F: Text;
840
  F: Text;
821
  rootoid: POID;
841
  rootoid: POID;
-
 
842
  rootfile: string;
822
begin
843
begin
823
  ClrScr;
844
  ClrScr;
824
  DrawTitleBar('TreeView Export', TITLEBAR_LEFT_TEXT, '');
845
  DrawTitleBar('TreeView Export', TITLEBAR_LEFT_TEXT, '');
825
  DrawStatusBar('Exporting data... please wait...');
846
  DrawStatusBar('Exporting data... please wait...');
826
 
847
 
-
 
848
  (* This will try creating a new root file if it does not exist *)
-
 
849
  rootfile := _GetRootFile(true);;
-
 
850
  if rootfile = '' then Exit;
-
 
851
 
827
  Assign(F, 'OIDTREE.TXT');
852
  Assign(F, 'OIDTREE.TXT');
828
  Rewrite(F);
853
  Rewrite(F);
829
 
854
 
830
  CreateOidDef(rootoid);
855
  CreateOidDef(rootoid);
831
  _ReadOidFile(_GetInitFile, rootoid);
856
  _ReadOidFile(rootfile, rootoid);
832
  _RecTreeExport(rootoid, F, 0);
857
  _RecTreeExport(rootoid, F, 0);
833
  FreeOidDef(rootoid);
858
  FreeOidDef(rootoid);
834
 
859
 
835
  DrawStatusBar(DEFAULT_STATUSBAR);
860
  DrawStatusBar(DEFAULT_STATUSBAR);
836
  ShowMessage('TreeView successfully exported as OIDTREE.TXT', 'TREEVIEW EXPORT', true);
861
  ShowMessage('TreeView successfully exported as OIDTREE.TXT', 'TREEVIEW EXPORT', true);
837
  _Pause;
862
  _Pause;
838
 
863
 
839
  Close(F);
864
  Close(F);
840
end;
865
end;
841
 
866
 
842
procedure OP_MainMenu;
867
procedure OP_MainMenu;
843
var
868
var
844
  menu: PStringList;
869
  menu: PStringList;
845
  menuRes, menuLeft, menuTop: integer;
870
  menuRes, menuLeft, menuTop: integer;
846
  menuIdOID, menuIdRA, menuIdTree, menuIdExit: integer;
871
  menuIdOID, menuIdRA, menuIdTree, menuIdExit: integer;
847
begin
872
begin
848
  repeat
873
  repeat
849
    ClrScr;
874
    ClrScr;
850
 
875
 
851
    DrawTitleBar('Welcome to OIDplus for DOS', '', '');
876
    DrawTitleBar('Welcome to OIDplus for DOS', '', '');
852
    DrawStatusBar(DEFAULT_STATUSBAR);
877
    DrawStatusBar(DEFAULT_STATUSBAR);
853
    GoToXY(ScreenWidth-Length(VERSIONINFO), ScreenHeight-1);
878
    GoToXY(ScreenWidth-Length(VERSIONINFO), ScreenHeight-1);
854
    Write(VERSIONINFO);
879
    Write(VERSIONINFO);
855
 
880
 
856
    CreateList(menu);
881
    CreateList(menu);
857
 
882
 
858
    menuIdOID  := ListAppend(menu, 'Manage OIDs');
883
    menuIdOID  := ListAppend(menu, 'Manage OIDs');
859
    menuIdRA   := -99; (*ListAppend(menu, 'Manage RAs');*)
884
    menuIdRA   := -99; (*ListAppend(menu, 'Manage RAs');*)
860
    menuIdTree := ListAppend(menu, 'Export TreeView');
885
    menuIdTree := ListAppend(menu, 'Export TreeView');
861
    menuIdExit := ListAppend(menu, 'Return to DOS');
886
    menuIdExit := ListAppend(menu, 'Return to DOS');
862
 
887
 
863
    menuLeft := round(ScreenWidth/2 -MAINMENU_WIDTH/2);
888
    menuLeft := round(ScreenWidth/2 -MAINMENU_WIDTH/2);
864
    menuTop  := round(ScreenHeight/2-MAINMENU_HEIGHT/2);
889
    menuTop  := round(ScreenHeight/2-MAINMENU_HEIGHT/2);
865
    menuRes  := DrawSelectionList(menuLeft, menuTop,
890
    menuRes  := DrawSelectionList(menuLeft, menuTop,
866
                                  MAINMENU_WIDTH, MAINMENU_HEIGHT,
891
                                  MAINMENU_WIDTH, MAINMENU_HEIGHT,
867
                                  menu, true, 'MAIN MENU', 2);
892
                                  menu, true, 'MAIN MENU', 2);
868
    FreeList(menu);
893
    FreeList(menu);
869
 
894
 
870
    if menuRes = menuIdOID then
895
    if menuRes = menuIdOID then
871
    begin
896
    begin
872
      OP_ManageOIDs;
897
      OP_ManageOIDs;
873
    end
898
    end
874
    else if menuRes = menuIdRA then
899
    else if menuRes = menuIdRA then
875
    begin
900
    begin
876
      OP_ManageRAs;
901
      OP_ManageRAs;
877
    end
902
    end
878
    else if menuRes = menuIdTree then
903
    else if menuRes = menuIdTree then
879
    begin
904
    begin
880
      OP_Treeview;
905
      OP_Treeview;
881
    end;
906
    end;
882
  until (menuRes = menuIdExit) or (MAINMENU_ALLOW_ESC and (menuRes = -1));
907
  until (menuRes = menuIdExit) or (MAINMENU_ALLOW_ESC and (menuRes = -1));
883
 
908
 
884
  OP_ReturnToMSDOS;
909
  OP_ReturnToMSDOS;
885
end;
910
end;
886
 
911
 
887
begin
912
begin
888
  OP_MainMenu;
913
  OP_MainMenu;
889
end.
914
end.
890
 
915