source: trunk/dll/walkem.c@ 1323

Last change on this file since 1323 was 1321, checked in by Steven Levine, 17 years ago

Rework casts variable types for OpenWatcom 1.8 compatibility
Add more FORTIFY support

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 44.5 KB
RevLine 
[123]1
2/***********************************************************************
3
4 $Id: walkem.c 1321 2008-12-07 01:48:06Z stevenhl $
5
[1077]6 Misc persistent lists support
7
[123]8 Copyright (c) 1993-98 M. Kimes
[1082]9 Copyright (c) 2005, 2008 Steven H. Levine
[123]10
[186]11 01 Aug 04 SHL Rework lstrip/rstrip usage
12 05 Jun 05 SHL Use QWL_USER
[242]13 13 Aug 05 SHL Run through indent
[259]14 13 Aug 05 SHL remove_udir - avoid corrupting last dirs list
[328]15 17 Jul 06 SHL Use Runtime_Error
[404]16 29 Jul 06 SHL Use xfgets
[518]17 20 Oct 06 SHL Correct . .. check
[544]18 06 Nov 06 SHL Oops - need to allow .. here
19 14 Nov 06 SHL Correct FillPathListBox regression
[574]20 22 Mar 07 GKY Use QWL_USER
[617]21 20 Apr 07 SHL Avoid spurious add_udir error reports
[787]22 16 Aug 07 SHL Update add_setups for ticket# 109
[789]23 19 Aug 07 SHL Correct load_setups error reporting
[794]24 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
[807]25 25 Aug 07 SHL Correct #pragma alloc_text typos
[864]26 11 Nov 07 GKY Cancel now directly closes dialog even if directory path text has changed
[939]27 20 Jan 08 GKY Walk & walk2 dialogs now save and restore size and position
[965]28 19 Feb 08 JBS Add "State at last FM/2 close" to the states combo box
[985]29 29 Feb 08 GKY Use xfree where appropriate
30 29 Feb 08 GKY Refactor global command line variables to notebook.h
[1027]31 19 Jun 08 JBS Ticket 227: Allow temporary saving/deleting of the shutdown state of directory containers
[1029]32 22 Jun 08 GKY Add free_?dir for fortify testing
[1078]33 18 Jul 08 SHL More Fortify support
[1082]34 19 Jul 08 GKY Replace save_dir2(dir) with pFM2SaveDirectory and use BldFullPathName
[1119]35 24 Aug 08 GKY Warn full drive on save of .DAT file; prevent loss of existing file
[123]36
37***********************************************************************/
38
[907]39#include <stdlib.h>
40#include <string.h>
41#include <ctype.h>
42#include <share.h>
43
[2]44#define INCL_WIN
45#define INCL_DOS
46#define INCL_DOSERRORS
[787]47#define INCL_SHLERRORS // PMERR_NOT_IN_IDX
[841]48#define INCL_LONGLONG
[2]49
[1186]50#include "fm3dll.h"
[1228]51#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
[1214]52#include "arccnrs.h" // Data declaration(s)
53#include "info.h" // Data declaration(s)
54#include "init.h" // Data declaration(s)
55#include "mainwnd.h" // Data declaration(s)
[2]56#include "fm3dlg.h"
57#include "fm3str.h"
[907]58#include "errutil.h" // Dos_Error...
59#include "strutil.h" // GetPString
[1077]60#include "notebook.h" // targetdirectory
[1082]61#include "pathutil.h" // BldFullPathName
[1162]62#include "walkem.h"
[1186]63#include "valid.h" // MakeFullName
64#include "chklist.h" // PosOverOkay
65#include "mkdir.h" // SetDir
66#include "wrappers.h" // xfgets
67#include "strips.h" // bstrip
68#include "misc.h" // CheckDriveSpaceAvail
69#include "dirs.h" // save_dir2
[1039]70#include "fortify.h"
[2]71
[242]72typedef struct
73{
[551]74 USHORT size;
75 USHORT changed;
76 BOOL nounwriteable;
77 CHAR szCurrentPath[CCHMAXPATH];
78 CHAR *szReturnPath;
79}
80WALKER;
[2]81
[1214]82static MRESULT EXPENTRY WalkTwoDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
83static VOID load_setups(VOID);
84static BOOL remove_ldir(PSZ path);
85
86// Data definitions
87#pragma data_seg(DATA1)
88
89static PSZ pszSrcFile = __FILE__;
[242]90static CHAR WalkFont[CCHMAXPATH] = "";
[2]91static ULONG WalkFontSize = sizeof(WalkFont);
92
[787]93/**
94 * States names management
95 */
96
97static BOOL fSetupsLoaded;
98static LINKDIRS *pFirstSetup;
99static const PSZ pszLastSetups = "LastSetups";
[907]100// 18 Aug 07 SHL fixme to stop supporting old style 1 year from now?
[787]101static const ULONG ulOldSetupsBytes = 100 * 13; // Prior to 3.0.7
102
[1214]103#pragma data_seg(GLOBAL1)
104BOOL fUdirsChanged;
105BOOL loadedudirs;
106
107#pragma data_seg(GLOBAL2)
108LINKDIRS *ldirhead;
109LINKDIRS *udirhead;
110
[787]111/**
112 * Fill States drop down list with known state names
113 */
114
115VOID fill_setups_list(VOID)
[242]116{
[787]117 WinSendMsg(hwndStatelist, LM_DELETEALL, MPVOID, MPVOID);
118 if (fUserComboBox) {
119 LINKDIRS *pld;
120 load_setups();
121 for (pld = pFirstSetup; pld; pld = pld->next) {
122 // DbgMsg(pszSrcFile, __LINE__, "Inserted %s", pld->path);
123 WinSendMsg(hwndStatelist,
124 LM_INSERTITEM,
125 MPFROM2SHORT(LIT_SORTASCENDING, 0),
126 MPFROMP(pld->path));
127 }
128 WinSetWindowText(hwndStatelist, GetPString(IDS_STATETEXT));
129 }
130}
[2]131
[787]132/**
133 * Lookup setup and do requested action
134 * @param - action, Support old/new style storage method
135 * @return 1 if found and action OK, 0 if not found and action OK, -1 if error during action
136 */
137
138#define LS_FIND 0
139#define LS_ADD 1
140#define LS_DELETE 2
141
142static INT lookup_setup(PSZ name, UINT action)
143{
144 LINKDIRS *pld;
145 LINKDIRS *pldLast = NULL;
146
147 if (!name || !*name) {
148 Runtime_Error(pszSrcFile, __LINE__, "no data");
149 return -1;
150 }
151
152 load_setups();
153
154 for (pld = pFirstSetup; pld; pld = pld->next) {
155 if (!stricmp(pld->path, name)) {
156 if (action == LS_DELETE) {
157 if (pldLast)
158 pldLast->next = pld->next;
159 else
160 pFirstSetup = pld->next;
[1009]161 xfree(pld->path, pszSrcFile, __LINE__);
[1039]162 free(pld);
[787]163 }
164 return 1; // Found or added
165 }
166 pldLast = pld; // In case deleting
167 } // for
168
169 // Not found
170 if (action == LS_ADD) {
171 pld = xmalloc(sizeof(LINKDIRS), pszSrcFile, __LINE__);
172 if (!pld)
173 return -1;
174 pld->path = xstrdup(name, pszSrcFile, __LINE__);
175 if (!pld->path) {
[1039]176 free(pld);
[787]177 return -1;
178 }
179 // Insert at front of list - drop down will sort
180 pld->next = pFirstSetup;
181 pFirstSetup = pld;
182 return 0;
183 }
184
185 return FALSE; // Not found
[2]186}
187
[787]188/**
189 * Load state names from ini
190 * Support old/new style storage method
191 */
192
193VOID load_setups(VOID)
[242]194{
[787]195 ULONG ulDataBytes;
196 ULONG l;
197 PSZ pszBuf;
198 PSZ psz;
199 LINKDIRS *pld;
200
201 if (fSetupsLoaded)
[551]202 return;
[787]203
204 if (!PrfQueryProfileSize(fmprof, FM3Str, pszLastSetups, &ulDataBytes)) {
205 // fixme to use generic hab
206 ERRORID eid = WinGetLastError((HAB)0);
207 if ((eid & 0xffff) != PMERR_NOT_IN_IDX) {
[789]208 // Get error info back
209 PrfQueryProfileSize(fmprof, FM3Str, pszLastSetups, &ulDataBytes);
210 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__, "PrfQueryProfileSize");
[787]211 }
[789]212 else
213 fSetupsLoaded = TRUE; // Nothing saved
214 return;
[787]215 }
216
217 if (ulDataBytes == 0) {
218 Runtime_Error(pszSrcFile, __LINE__, "PrfQueryProfileSize reported 0 bytes");
219 return;
220 }
221
222 pszBuf = xmalloc(ulDataBytes + 1, pszSrcFile, __LINE__); // One extra for end marker
223 if (!pszBuf)
224 return;
225 l = ulDataBytes;
226 if (!PrfQueryProfileData(fmprof, FM3Str, pszLastSetups, pszBuf, &l)) {
227 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__, "PrfQueryProfileData");
[1039]228 free(pszBuf);
[787]229 return;
230 }
231
232 if (ulDataBytes != l) {
233 Runtime_Error(pszSrcFile, __LINE__, "PrfQueryProfileData reported %u expected %u", l, ulDataBytes);
[1039]234 free(pszBuf);
[787]235 return;
236 }
237
238 *(pszBuf + ulDataBytes) = 0; // Insert end marker
239
240 psz = pszBuf;
241 if (!*psz && ulDataBytes == ulOldSetupsBytes)
242 psz += 13; // Rarely used 1st fixed width entry prior to 3.0.7
243
244 while (*psz) {
245 pld = xmalloc(sizeof(LINKDIRS), pszSrcFile, __LINE__);
246 if (!pld) {
[1039]247 free(pszBuf);
[787]248 return;
249 }
[1078]250
251# ifdef FORTIFY
252 Fortify_SetOwner(pld, 1);
253 Fortify_SetScope(pld, 1);
254# endif
255
[787]256 pld->path = xstrdup(psz, pszSrcFile, __LINE__);
257 if (!pld->path) {
[1039]258 free(pszBuf);
259 free(pld);
[787]260 return;
261 }
262
[1078]263# ifdef FORTIFY
264 Fortify_SetOwner(pld->path, 1);
265 Fortify_SetScope(pld->path, 1);
266# endif
267
[787]268 // Insert at front of list - drop down will sort
269 pld->next = pFirstSetup;
270 pFirstSetup = pld;
271 // DbgMsg(pszSrcFile, __LINE__, "Inserted %s", pld->path);
272
273 if (ulDataBytes == ulOldSetupsBytes)
274 psz += 13; // Buffers fixed width prior to 3.0.7
275 else
276 psz += strlen(psz) + 1;
277 } // while
278
[1039]279 free(pszBuf);
[787]280
281 fSetupsLoaded = TRUE;
[2]282}
283
[787]284VOID save_setups(VOID)
[242]285{
[787]286 ULONG ulBufBytes;
287 ULONG ulFillBytes;
288 ULONG l;
289 PSZ pszBuf;
290 PSZ psz;
291 LINKDIRS *pld;
[2]292
[787]293 if (!fSetupsLoaded)
294 return;
295
296 ulBufBytes = 0;
297 for (pld = pFirstSetup; pld; pld = pld->next) {
298 ulBufBytes += strlen(pld->path) + 1;
299 } // for
300
301 if (!ulBufBytes)
302 pszBuf = NULL;
303 else {
304 // Ensure different than size prior to 3.0.7
305 ulFillBytes = ulBufBytes == ulOldSetupsBytes ? 1 : 0;
306 pszBuf = xmalloc(ulBufBytes + ulFillBytes, pszSrcFile, __LINE__);
307 if (!pszBuf)
308 return;
309
310 psz = pszBuf;
311 for (pld = pFirstSetup; pld; pld = pld->next) {
312 l = strlen(pld->path) + 1;
313 memcpy(psz, pld->path, l);
314 psz += l;
315 } // for
316 if (ulFillBytes)
317 *psz = 0;
[551]318 }
[787]319
320 if (!PrfWriteProfileData(fmprof,
321 FM3Str,
322 pszLastSetups, pszBuf, ulBufBytes)) {
323 // Win_Error(pszSrcFile, __LINE__, HWND_DESKTOP, HWND_DESKTOP, "PrfWriteProfileData");
324 ERRORID eid = WinGetLastError((HAB)0);
325 if ((eid & 0xffff) != PMERR_NOT_IN_IDX)
326 Runtime_Error(pszSrcFile, __LINE__, "PrfWriteProfileData returned %u", eid);
327 }
328
329 // Delete obsolete INI entry
330 PrfWriteProfileData(fmprof, FM3Str, "LastSetup", NULL, 0);
[2]331}
332
[787]333/**
334 * Add named state to setups list
335 * @return same as lookup_setup
336 */
337
338INT add_setup(PSZ name)
[242]339{
[787]340 return lookup_setup(name, LS_ADD);
341}
[2]342
[787]343/**
344 * Delete named state from setups list
345 * @return same as lookup_setup
346 */
347
348INT remove_setup(PSZ name)
349{
350 return lookup_setup(name, LS_DELETE);
[2]351}
352
[1077]353#ifdef FORTIFY
354
355VOID free_setups(VOID)
356{
357 LINKDIRS *pld = pFirstSetup;
358 while (pld) {
359 LINKDIRS *next = pld->next;
360 free(pld->path);
361 free(pld);
362 pld = next;
363 }
364 pFirstSetup = NULL;
365}
366
367#endif // FORTIFY
368
[242]369VOID load_udirs(VOID)
370{
[551]371 /* load linked list of user directories from USERDIRS.DAT file */
[2]372
[551]373 FILE *fp;
374 LINKDIRS *info;
375 LINKDIRS *last = NULL;
376 CHAR s[CCHMAXPATH + 24];
[2]377
[1034]378 if (udirhead)
379 free_udirs();
[551]380 loadedudirs = TRUE;
381 fUdirsChanged = FALSE;
[1082]382 BldFullPathName(s, pFM2SaveDirectory, "USERDIRS.DAT");
[551]383 fp = _fsopen(s, "r", SH_DENYWR);
384 if (fp) {
385 while (!feof(fp)) {
386 if (!xfgets(s, CCHMAXPATH + 24, fp, pszSrcFile, __LINE__))
387 break;
388 s[CCHMAXPATH] = 0;
389 bstripcr(s);
390 if (*s && *s != ';') {
391 info = xmalloc(sizeof(LINKDIRS), pszSrcFile, __LINE__);
[1078]392# ifdef FORTIFY
393 Fortify_SetOwner(info, 1);
394 Fortify_SetScope(info, 1);
395# endif
[551]396 if (info) {
397 info->path = xstrdup(s, pszSrcFile, __LINE__);
398 if (!info->path)
[1039]399 free(info);
[551]400 else {
[1078]401# ifdef FORTIFY
402 Fortify_SetOwner(info->path, 1);
403 Fortify_SetScope(info->path, 1);
404# endif
[551]405 info->next = NULL;
406 if (!udirhead)
407 udirhead = info;
408 else
409 last->next = info;
410 last = info;
411 }
[242]412 }
[551]413 }
[2]414 }
[551]415 fclose(fp);
416 }
[2]417}
418
[242]419VOID save_udirs(VOID)
420{
[551]421 FILE *fp;
422 LINKDIRS *info;
423 CHAR s[CCHMAXPATH + 14];
[2]424
[551]425 if (loadedudirs) {
426 fUdirsChanged = FALSE;
427 if (udirhead) {
[1082]428 BldFullPathName(s, pFM2SaveDirectory, "USERDIRS.DAT");
[1118]429 if (CheckDriveSpaceAvail(s, ullDATFileSpaceNeeded, 1) == 2)
[1117]430 return; //already gave error msg
[551]431 fp = xfopen(s, "w", pszSrcFile, __LINE__);
432 if (fp) {
433 fputs(GetPString(IDS_USERDEFDIRSTEXT), fp);
434 info = udirhead;
435 while (info) {
436 fprintf(fp, "%0.*s\n", CCHMAXPATH, info->path);
437 info = info->next;
[242]438 }
[551]439 fclose(fp);
440 }
[2]441 }
[551]442 }
[2]443}
444
[617]445/**
446 * Add path to user directory list or last used directory list.
447 * Callers need to check fUdirsChanged to know if user dirs change occured.
448 * Callers need to check return code to know if last dirs change occured.
449 * @param userdirs TRUE to process user directory list. Otherwise last used list.
450 * @return TRUE if added, FALSE if already in list or error.
451 */
[259]452
[617]453BOOL add_udir(BOOL userdirs, CHAR *inpath)
[242]454{
[551]455 CHAR path[CCHMAXPATH];
456 LINKDIRS *info;
457 LINKDIRS *last = NULL;
458 LINKDIRS *temp;
[2]459
[551]460 if (inpath && *inpath) {
461 if (DosQueryPathInfo(inpath, FIL_QUERYFULLNAME, path, sizeof(path)))
462 strcpy(path, inpath);
463 if (!userdirs && IsRoot(path))
464 return FALSE;
465 if (IsFullName(path)) {
466 if (!loadedudirs)
467 load_udirs();
468 // Search user dir list first unless doing last dirs
469 info = userdirs ? udirhead : ldirhead;
470 while (info) {
471 if (!stricmp(info->path, path))
472 return FALSE; // Already in list
473 last = info; // Remember append to location
474 info = info->next;
475 }
476 // Search last dir list unless doing just last dirs
477 if (!userdirs) {
478 info = udirhead;
479 while (info) {
480 if (!stricmp(info->path, path))
[242]481 return FALSE;
[551]482 info = info->next;
483 }
484 }
485 else {
486 /* if adding manual directory, remove from auto list if present */
487 info = ldirhead;
488 temp = NULL;
489 while (info) {
490 if (!stricmp(info->path, path)) {
491 if (temp)
492 temp->next = info->next;
[242]493 else
[551]494 ldirhead = info->next;
[1009]495 xfree(info->path, pszSrcFile, __LINE__);
[1039]496 free(info);
[551]497 break;
498 }
499 temp = info;
500 info = info->next;
[242]501 }
[551]502 }
503 // Append entry to end of user dirs list
504 info = xmalloc(sizeof(LINKDIRS), pszSrcFile, __LINE__);
505 if (info) {
[1078]506# ifdef FORTIFY
507 Fortify_SetScope(info, 1);
508# endif
[551]509 info->path = xstrdup(path, pszSrcFile, __LINE__);
510 if (!info->path)
[1039]511 free(info);
[551]512 else {
[1078]513# ifdef FORTIFY
514 Fortify_SetScope(info->path, 1);
515# endif
[551]516 info->next = NULL;
517 if (userdirs) {
518 fUdirsChanged = TRUE;
519 if (!udirhead)
520 udirhead = info;
521 else
522 last->next = info;
523 }
524 else {
525 if (!ldirhead)
526 ldirhead = info;
527 else
528 last->next = info;
[1077]529 }
[551]530 return TRUE;
531 }
532 }
[2]533 }
[551]534 }
535 return FALSE;
[2]536}
537
[259]538//=== remove_udir - remove path from user dir list or last directory list ===
539
[242]540BOOL remove_udir(CHAR * path)
541{
[551]542 LINKDIRS *info;
543 LINKDIRS *last = NULL;
[2]544
[551]545 if (path && *path) {
546 if (!loadedudirs)
547 load_udirs();
548 info = udirhead;
549 while (info) {
550 if (!stricmp(info->path, path)) {
551 if (last)
552 last->next = info->next;
553 else
554 udirhead = info->next;
[1009]555 xfree(info->path, pszSrcFile, __LINE__);
[1039]556 free(info);
[551]557 fUdirsChanged = TRUE;
558 return TRUE;
559 }
560 last = info;
561 info = info->next;
562 }
[259]563
[551]564 info = ldirhead;
565 last = NULL;
566 while (info) {
567 if (!stricmp(info->path, path)) {
568 if (last)
569 last->next = info->next;
570 else
571 ldirhead = info->next;
[1009]572 xfree(info->path, pszSrcFile, __LINE__);
[1039]573 free(info);
[551]574 return TRUE;
575 }
576 last = info;
577 info = info->next;
[2]578 }
[551]579 }
580 return FALSE;
[2]581}
582
[242]583BOOL remove_ldir(CHAR * path)
584{
[551]585 LINKDIRS *info;
586 LINKDIRS *last = NULL;
[2]587
[551]588 if (path && *path) {
589 info = ldirhead;
590 while (info) {
591 if (!stricmp(info->path, path)) {
592 if (last)
593 last->next = info->next;
594 else
595 ldirhead = info->next;
[1009]596 xfree(info->path, pszSrcFile, __LINE__);
[1039]597 free(info);
[551]598 return TRUE;
599 }
600 last = info;
601 info = info->next;
[2]602 }
[551]603 }
604 return FALSE;
[2]605}
606
[1082]607# ifdef FORTIFY
608
[1029]609VOID free_ldir(VOID)
610{
611 LINKDIRS *info, *next;
612
613 info = ldirhead;
614 while (info) {
615 next = info->next;
616 xfree(info->path, pszSrcFile, __LINE__);
[1039]617 free(info);
[1029]618 info = next;
619 }
620 ldirhead = NULL;
621}
622
[1082]623# endif
624
[1034]625VOID free_udirs(VOID)
[1029]626{
627 LINKDIRS *info, *next;
628
629 info = udirhead;
630 while (info) {
631 next = info->next;
632 xfree(info->path, pszSrcFile, __LINE__);
[1039]633 free(info);
[1029]634 info = next;
635 }
636 udirhead = NULL;
637}
638
[551]639VOID FillPathListBox(HWND hwnd, HWND hwnddrive, HWND hwnddir, CHAR * pszPath,
[242]640 BOOL nounwriteable)
641{
[551]642 /*
643 * this function fills one or two list boxes with drive and directory
644 * information showing all available drives and all directories off of
645 * the directory represented by path. This works independently of the
646 * current directory.
647 */
[2]648
[551]649 CHAR szDrive[] = " :", szTemp[1032];
[847]650 FILEFINDBUF3 findbuf;
[551]651 HDIR hDir = HDIR_CREATE;
652 SHORT sDrive;
[766]653 ULONG ulDriveNum, ulSearchCount = 1, ulDriveMap;
[2]654
[551]655 DosError(FERR_DISABLEHARDERR);
656 DosQCurDisk(&ulDriveNum, &ulDriveMap);
657 if (hwnddrive)
658 WinSendMsg(hwnddrive, LM_DELETEALL, MPVOID, MPVOID);
659 if (hwnddrive != hwnddir && hwnddir)
660 WinSendMsg(hwnddir, LM_DELETEALL, MPVOID, MPVOID);
[2]661
[551]662 if (hwnddrive) {
663 // Fill drive listbox
664 for (sDrive = 0; sDrive < 26; sDrive++) {
[766]665 if (ulDriveMap & (1 << sDrive)) {
[551]666 *szDrive = (CHAR) (sDrive + 'A');
667 if ((!nounwriteable || !(driveflags[sDrive] & DRIVE_NOTWRITEABLE)) &&
668 !(driveflags[sDrive] & (DRIVE_IGNORE | DRIVE_INVALID)))
669 WinSendMsg(hwnddrive, LM_INSERTITEM, MPFROM2SHORT(LIT_END, 0),
670 MPFROMP(szDrive));
671 }
[2]672 }
[551]673 if (hwnddrive != hwnddir && pszPath && isalpha(*pszPath)
674 && pszPath[1] == ':') {
675 *szDrive = toupper(*pszPath);
676 WinSetWindowText(hwnddrive, szDrive);
677 }
678 }
[2]679
[551]680 if (hwnddir) {
681 // Fill directory listbox
682 sprintf(szTemp,
683 "%s%s*",
684 pszPath, (pszPath[strlen(pszPath) - 1] == '\\') ? "" : "\\");
685 DosError(FERR_DISABLEHARDERR);
[847]686 if (!DosFindFirst(szTemp,
687 &hDir,
688 FILE_DIRECTORY | MUST_HAVE_DIRECTORY |
689 FILE_READONLY | FILE_ARCHIVED | FILE_SYSTEM |
690 FILE_HIDDEN,
691 &findbuf,
692 sizeof(FILEFINDBUF3), &ulSearchCount, FIL_STANDARD)) {
[551]693 do {
694 if (findbuf.attrFile & FILE_DIRECTORY) {
695 // Skip .. unless full path supplied
696 if (strcmp(findbuf.achName, "..") ||
697 strlen(pszPath) > 3 || pszPath[1] != ':') {
698 // Skip . allow ..
699 if (findbuf.achName[0] != '.' || findbuf.achName[1]) {
700 WinSendMsg(hwnddir,
701 LM_INSERTITEM,
702 MPFROM2SHORT(LIT_SORTASCENDING, 0),
703 MPFROMP(findbuf.achName));
704 }
705 }
[242]706 }
[766]707 ulSearchCount = 1;
[847]708 } while (!DosFindNext(hDir,
709 &findbuf, sizeof(FILEFINDBUF3), &ulSearchCount));
[551]710 DosFindClose(hDir);
[2]711 }
[551]712 DosError(FERR_DISABLEHARDERR);
713 }
[2]714}
715
[242]716MRESULT EXPENTRY TextSubProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
717{
[574]718 PFNWP oldproc = (PFNWP) WinQueryWindowPtr(hwnd, QWL_USER);
[2]719
[551]720 switch (msg) {
721 case WM_CHAR:
722 if (SHORT1FROMMP(mp1) & KC_KEYUP) {
723 if ((SHORT1FROMMP(mp1) & KC_VIRTUALKEY) &&
724 (SHORT1FROMMP(mp2) & 255) == '\r')
725 PostMsg(WinQueryWindow(hwnd, QW_PARENT), WM_COMMAND,
726 MPFROM2SHORT(DID_OK, 0), MPVOID);
[242]727 }
[551]728 break;
729 }
730 return oldproc(hwnd, msg, mp1, mp2);
[2]731}
732
[242]733MRESULT EXPENTRY WalkDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
734{
[551]735 WALKER *wa;
736 CHAR szBuff[CCHMAXPATH + 1], szBuffer[CCHMAXPATH + 1], *p;
737 SHORT sSelect;
738 static BOOL okay; /* avoid combobox selecting as filled */
739 static CHAR lastdir[CCHMAXPATH + 1];
[2]740
[551]741 switch (msg) {
742 case UM_SETUP2:
743 case WM_INITDLG:
744 okay = FALSE;
745 *lastdir = 0;
746 if (!mp2) {
747 Runtime_Error2(pszSrcFile, __LINE__, IDS_NODATATEXT);
748 WinDismissDlg(hwnd, 0);
749 break;
750 }
751 wa = xmallocz(sizeof(WALKER), pszSrcFile, __LINE__);
752 if (!wa) {
753 WinDismissDlg(hwnd, 0);
754 break;
755 }
756 wa->size = (USHORT) sizeof(WALKER);
[574]757 WinSetWindowPtr(hwnd, QWL_USER, (PVOID) wa);
[1009]758 wa->szReturnPath = (CHAR *)mp2;
[242]759 {
[551]760 PFNWP oldproc;
[2]761
[551]762 oldproc = WinSubclassWindow(WinWindowFromID(hwnd, WALK_PATH),
763 (PFNWP) TextSubProc);
764 if (oldproc)
765 WinSetWindowPtr(WinWindowFromID(hwnd, WALK_PATH),
766 QWL_USER, (PVOID) oldproc);
767 WinSendDlgItemMsg(WinWindowFromID(hwnd, WALK_RECENT),
768 CBID_EDIT,
769 EM_SETTEXTLIMIT, MPFROM2SHORT(CCHMAXPATH, 0), MPVOID);
770 WinSendDlgItemMsg(WinWindowFromID(hwnd, WALK_RECENT),
771 CBID_EDIT,
772 EM_SETREADONLY, MPFROM2SHORT(TRUE, 0), MPVOID);
773 }
[939]774 {
775 SWP swp;
776 ULONG size = sizeof(SWP);
777
778 PrfQueryProfileData(fmprof, FM3Str, "WalkDir.Position", (PVOID) &swp, &size);
779 WinSetWindowPos(hwnd,
[1077]780 HWND_TOP,
781 swp.x,
782 swp.y,
783 swp.cx,
784 swp.cy,
785 swp.fl);
[939]786 }
[551]787 PosOverOkay(hwnd);
788 if (msg == UM_SETUP2)
789 wa->nounwriteable = FALSE;
790 else
791 wa->nounwriteable = TRUE;
792 if (!*wa->szReturnPath)
[1104]793 strcpy(wa->szCurrentPath, pFM2SaveDirectory);
[551]794 else {
795 strcpy(wa->szCurrentPath, wa->szReturnPath);
796 MakeFullName(wa->szCurrentPath);
797 }
798 if (wa->nounwriteable &&
799 (driveflags[toupper(*wa->szCurrentPath) - 'A'] &
800 DRIVE_NOTWRITEABLE)) {
[2]801
[551]802 ULONG bd;
[2]803
[551]804 strcpy(wa->szCurrentPath, "C:\\");
805 if (DosQuerySysInfo(QSV_BOOT_DRIVE,
806 QSV_BOOT_DRIVE,
807 (PVOID) & bd, (ULONG) sizeof(ULONG)))
[766]808 bd = 3;
[551]809 *wa->szCurrentPath = (CHAR) bd + '@';
810 }
811 WinSendDlgItemMsg(hwnd,
812 WALK_PATH,
813 EM_SETTEXTLIMIT, MPFROM2SHORT(CCHMAXPATH, 0), MPVOID);
814 WinSetDlgItemText(hwnd, WALK_PATH, wa->szCurrentPath);
815 if (!loadedudirs)
816 load_udirs();
817 { /* fill user list box */
818 ULONG ulDriveNum, ulDriveMap;
819 ULONG ulSearchCount;
[847]820 FILEFINDBUF3 findbuf;
[551]821 HDIR hDir;
822 APIRET rc;
823 LINKDIRS *info, *temp;
[2]824
[551]825 DosError(FERR_DISABLEHARDERR);
826 DosQCurDisk(&ulDriveNum, &ulDriveMap);
827 info = udirhead;
828 while (info) {
829 if (IsFullName(info->path) &&
830 !(driveflags[toupper(*info->path) - 'A'] &
831 (DRIVE_IGNORE | DRIVE_INVALID))) {
832 DosError(FERR_DISABLEHARDERR);
833 hDir = HDIR_CREATE;
[766]834 ulSearchCount = 1;
[551]835 if (!IsRoot(info->path))
[847]836 rc = DosFindFirst(info->path, &hDir, FILE_DIRECTORY |
837 MUST_HAVE_DIRECTORY | FILE_READONLY |
838 FILE_ARCHIVED | FILE_SYSTEM | FILE_HIDDEN,
839 &findbuf, sizeof(FILEFINDBUF3),
840 &ulSearchCount, FIL_STANDARD);
[551]841 else {
842 rc = 0;
843 findbuf.attrFile = FILE_DIRECTORY;
844 }
845 if (!rc) {
846 if (!IsRoot(info->path))
847 DosFindClose(hDir);
848 if (findbuf.attrFile & FILE_DIRECTORY)
849 WinSendDlgItemMsg(hwnd, WALK_USERLIST, LM_INSERTITEM,
850 MPFROM2SHORT(LIT_SORTASCENDING, 0),
851 MPFROMP(info->path));
852 else {
853 temp = info->next;
854 remove_udir(info->path);
855 info = temp;
856 continue;
[242]857 }
[551]858 }
[766]859 else if (!(ulDriveMap & (1 << (toupper(*info->path) - 'A')))) {
[551]860 temp = info->next;
861 remove_udir(info->path);
862 info = temp;
863 continue;
864 }
865 }
866 info = info->next;
867 }
868 info = ldirhead;
869 while (info) {
870 if (IsFullName(info->path) &&
871 !(driveflags[toupper(*info->path) - 'A'] &
872 (DRIVE_IGNORE | DRIVE_INVALID))) {
873 DosError(FERR_DISABLEHARDERR);
874 hDir = HDIR_CREATE;
[766]875 ulSearchCount = 1;
[551]876 if (!IsRoot(info->path))
[847]877 rc = DosFindFirst(info->path, &hDir, FILE_DIRECTORY |
878 MUST_HAVE_DIRECTORY | FILE_READONLY |
879 FILE_ARCHIVED | FILE_SYSTEM | FILE_HIDDEN,
880 &findbuf, sizeof(FILEFINDBUF3),
881 &ulSearchCount, FIL_STANDARD);
[551]882 else {
883 rc = 0;
884 findbuf.attrFile = FILE_DIRECTORY;
885 }
886 if (!rc) {
887 if (!IsRoot(info->path))
888 DosFindClose(hDir);
889 if (findbuf.attrFile & FILE_DIRECTORY)
890 WinSendDlgItemMsg(hwnd, WALK_RECENT, LM_INSERTITEM,
891 MPFROM2SHORT(LIT_SORTASCENDING, 0),
892 MPFROMP(info->path));
893 else {
894 temp = info->next;
895 remove_ldir(info->path);
896 info = temp;
897 continue;
[242]898 }
[551]899 WinSetDlgItemText(hwnd, WALK_RECENT,
900 GetPString(IDS_WALKRECENTDIRSTEXT));
901 }
[766]902 else if (!(ulDriveMap & (1 << (toupper(*info->path) - 'A')))) {
[551]903 temp = info->next;
904 remove_ldir(info->path);
905 info = temp;
906 continue;
907 }
[242]908 }
[551]909 info = info->next;
910 }
911 }
912 FillPathListBox(hwnd,
913 WinWindowFromID(hwnd, WALK_DRIVELIST),
914 WinWindowFromID(hwnd, WALK_DIRLIST),
915 wa->szCurrentPath, wa->nounwriteable);
916 if (!PostMsg(hwnd, UM_SETUP4, MPVOID, MPVOID))
917 okay = TRUE;
918 {
919 MRESULT ret;
[2]920
[551]921 ret = WinDefDlgProc(hwnd, WM_INITDLG, mp1, mp2);
922 WinSendMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
923 WinInvalidateRect(WinWindowFromID(hwnd, WALK_PATH), NULL, TRUE);
924 return ret;
925 }
[2]926
[551]927 case UM_SETUP4:
928 okay = TRUE;
929 return 0;
[2]930
[551]931 case WM_ADJUSTWINDOWPOS:
932 PostMsg(hwnd, UM_SETDIR, MPVOID, MPVOID);
933 break;
[2]934
[551]935 case UM_SETDIR:
936 PaintRecessedWindow(WinWindowFromID(hwnd, WALK_HELP), (HPS) 0, FALSE,
937 TRUE);
938 return 0;
[2]939
[551]940 case WM_PRESPARAMCHANGED:
941 {
942 ULONG AttrFound, AttrValue[64], cbRetLen;
[2]943
[551]944 cbRetLen = WinQueryPresParam(hwnd, (ULONG) mp1, 0, &AttrFound,
945 (ULONG) sizeof(AttrValue), &AttrValue, 0);
946 if (cbRetLen) {
947 switch (AttrFound) {
948 case PP_FONTNAMESIZE:
949 PrfWriteProfileData(fmprof,
950 appname,
951 "WalkFont", (PVOID) AttrValue, cbRetLen);
952 *WalkFont = 0;
953 WalkFontSize = sizeof(WalkFont);
954 WinInvalidateRect(WinWindowFromID(hwnd, WALK_PATH), NULL, TRUE);
955 break;
[242]956 }
[551]957 }
958 }
959 break;
[2]960
[551]961 case UM_SETUP3:
962 save_udirs();
963 if (hwndMain)
964 PostMsg(hwndMain, UM_FILLUSERLIST, MPVOID, MPVOID);
965 return 0;
[2]966
[551]967 case UM_SETUP:
968 {
969 INT x;
970 USHORT id[] = { WALK_PATH, WALK_DIRLIST, WALK_USERLIST,
971 WALK_RECENT, 0
972 };
[2]973
[551]974 if (*WalkFont ||
975 (PrfQueryProfileData(fmprof,
976 appname,
977 "WalkFont",
978 (PVOID) WalkFont,
979 &WalkFontSize) && WalkFontSize)) {
980 for (x = 0; id[x]; x++)
981 WinSetPresParam(WinWindowFromID(hwnd, id[x]),
982 PP_FONTNAMESIZE, WalkFontSize, (PVOID) WalkFont);
983 }
984 }
985 return 0;
[2]986
[551]987 case UM_CONTROL:
988 case WM_CONTROL:
[574]989 wa = WinQueryWindowPtr(hwnd, QWL_USER);
[551]990 if (SHORT1FROMMP(mp1) == WALK_DRIVELIST ||
991 SHORT1FROMMP(mp1) == WALK_DIRLIST ||
992 SHORT1FROMMP(mp1) == WALK_USERLIST ||
993 SHORT1FROMMP(mp1) == WALK_RECENT) {
994 sSelect = (USHORT) WinSendDlgItemMsg(hwnd,
995 SHORT1FROMMP(mp1),
996 LM_QUERYSELECTION, MPVOID, MPVOID);
997 *szBuffer = 0;
998 if (sSelect >= 0)
999 WinSendDlgItemMsg(hwnd, SHORT1FROMMP(mp1), LM_QUERYITEMTEXT,
1000 MPFROM2SHORT(sSelect, CCHMAXPATH),
1001 MPFROMP(szBuffer));
1002 }
1003 switch (SHORT1FROMMP(mp1)) {
1004 case WALK_PATH:
1005 if (SHORT2FROMMP(mp1) == EN_SETFOCUS)
1006 WinSetDlgItemText(hwnd, WALK_HELP, GetPString(IDS_WALKCURRDIRTEXT));
1007 else if (SHORT2FROMMP(mp1) == EN_KILLFOCUS)
1008 WinSetDlgItemText(hwnd, WALK_HELP,
1009 GetPString(IDS_WALKDEFAULTHELPTEXT));
1010 break;
[2]1011
[551]1012 case WALK_RECENT:
1013 if (okay && SHORT2FROMMP(mp1) == CBN_LBSELECT) {
[2]1014
[551]1015 ULONG ulSearchCount;
[847]1016 FILEFINDBUF3 findbuf;
[551]1017 HDIR hDir;
1018 APIRET rc;
[2]1019
[551]1020 // *szBuffer = 0;
1021 // WinQueryDlgItemText(hwnd,WALK_RECENT,CCHMAXPATH,szBuffer);
1022 if (!*szBuffer)
1023 break;
1024 DosError(FERR_DISABLEHARDERR);
1025 hDir = HDIR_CREATE;
[766]1026 ulSearchCount = 1;
[551]1027 if (!IsRoot(szBuffer)) {
[847]1028 rc = DosFindFirst(szBuffer, &hDir, FILE_DIRECTORY |
1029 MUST_HAVE_DIRECTORY | FILE_READONLY |
1030 FILE_ARCHIVED | FILE_SYSTEM | FILE_HIDDEN,
1031 &findbuf, sizeof(FILEFINDBUF3),
1032 &ulSearchCount, FIL_STANDARD);
[551]1033 if (!rc)
1034 DosFindClose(hDir);
1035 }
1036 else {
1037 findbuf.attrFile = FILE_DIRECTORY;
1038 rc = 0;
1039 }
1040 if (rc)
1041 Dos_Error(MB_CANCEL, rc, hwnd, pszSrcFile, __LINE__,
[838]1042 "xDosFindFirst");
[551]1043 else if (~findbuf.attrFile & FILE_DIRECTORY)
1044 Runtime_Error(pszSrcFile, __LINE__, "not a directory");
1045 else {
1046 strcpy(wa->szCurrentPath, szBuffer);
1047 WinSetDlgItemText(hwnd, WALK_PATH, wa->szCurrentPath);
1048 WinSetDlgItemText(hwnd, WALK_RECENT, wa->szCurrentPath);
1049 FillPathListBox(hwnd,
1050 WinWindowFromID(hwnd, WALK_DRIVELIST),
1051 WinWindowFromID(hwnd, WALK_DIRLIST),
1052 wa->szCurrentPath, FALSE);
1053 }
1054 }
1055 else if (SHORT2FROMMP(mp1) == CBN_ENTER)
1056 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(DID_OK, 0), MPVOID);
1057 else if (SHORT2FROMMP(mp1) == CBN_SHOWLIST)
1058 WinSetDlgItemText(hwnd, WALK_HELP,
1059 GetPString(IDS_WALKRECENTDIRSHELPTEXT));
1060 break;
[2]1061
[551]1062 case WALK_USERLIST:
1063 if (okay && *szBuffer && SHORT2FROMMP(mp1) == LN_SELECT) {
[2]1064
[551]1065 ULONG ulSearchCount;
[847]1066 FILEFINDBUF3 findbuf;
[551]1067 HDIR hDir;
1068 APIRET rc;
[2]1069
[551]1070 DosError(FERR_DISABLEHARDERR);
1071 hDir = HDIR_CREATE;
[766]1072 ulSearchCount = 1;
[551]1073 if (!IsRoot(szBuffer)) {
[847]1074 rc = DosFindFirst(szBuffer,
1075 &hDir,
1076 FILE_DIRECTORY |
1077 MUST_HAVE_DIRECTORY | FILE_READONLY |
1078 FILE_ARCHIVED | FILE_SYSTEM | FILE_HIDDEN,
1079 &findbuf,
1080 sizeof(FILEFINDBUF3),
1081 &ulSearchCount, FIL_STANDARD);
[551]1082 if (!rc)
1083 DosFindClose(hDir);
1084 }
1085 else {
1086 findbuf.attrFile = FILE_DIRECTORY;
1087 rc = 0;
1088 }
1089 if (rc)
1090 Dos_Error(MB_CANCEL, rc, hwnd, pszSrcFile, __LINE__,
[838]1091 "xDosFindFirst");
[551]1092 else if (~findbuf.attrFile & FILE_DIRECTORY)
1093 Runtime_Error(pszSrcFile, __LINE__, "not a directory");
1094 else {
1095 strcpy(wa->szCurrentPath, szBuffer);
1096 WinSetDlgItemText(hwnd, WALK_PATH, wa->szCurrentPath);
1097 FillPathListBox(hwnd,
1098 WinWindowFromID(hwnd, WALK_DRIVELIST),
1099 WinWindowFromID(hwnd, WALK_DIRLIST),
1100 wa->szCurrentPath, FALSE);
1101 }
1102 }
1103 else if (SHORT2FROMMP(mp1) == LN_ENTER)
1104 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(DID_OK, 0), MPVOID);
1105 else if (SHORT2FROMMP(mp1) == LN_SETFOCUS)
1106 WinSetDlgItemText(hwnd,
1107 WALK_HELP, GetPString(IDS_WALKUSERDIRSHELPTEXT));
1108 else if (SHORT2FROMMP(mp1) == LN_KILLFOCUS)
1109 WinSetDlgItemText(hwnd,
1110 WALK_HELP, GetPString(IDS_WALKDEFAULTHELPTEXT));
1111 break;
[2]1112
[551]1113 case WALK_DRIVELIST:
1114 if (okay && *szBuffer && SHORT2FROMMP(mp1) == LN_ENTER) {
[2]1115
[551]1116 ULONG ulDirLen = CCHMAXPATH;
1117 APIRET rc;
[2]1118
[1321]1119 rc = DosQCurDir(toupper(*szBuffer) - '@', (PBYTE)&szBuff[3], &ulDirLen);
[551]1120 if (!rc) {
1121 strcpy(wa->szCurrentPath, "C:\\");
1122 *wa->szCurrentPath = toupper(*szBuffer);
1123 WinSetDlgItemText(hwnd, WALK_PATH, wa->szCurrentPath);
1124 FillPathListBox(hwnd,
1125 WinWindowFromID(hwnd, WALK_DRIVELIST),
1126 WinWindowFromID(hwnd, WALK_DIRLIST),
1127 wa->szCurrentPath, FALSE);
1128 }
1129 }
1130 else if (SHORT2FROMMP(mp1) == LN_SETFOCUS)
1131 WinSetDlgItemText(hwnd, WALK_HELP,
1132 GetPString(IDS_WALKDRIVELISTHELPTEXT));
1133 else if (SHORT2FROMMP(mp1) == LN_KILLFOCUS)
1134 WinSetDlgItemText(hwnd, WALK_HELP,
1135 GetPString(IDS_WALKDEFAULTHELPTEXT));
1136 break;
[2]1137
[551]1138 case WALK_DIRLIST:
1139 if (okay && SHORT2FROMMP(mp1) == LN_ENTER) {
[2]1140
[551]1141 ULONG ulSearchCount;
[847]1142 FILEFINDBUF3 findbuf;
[551]1143 HDIR hDir;
1144 APIRET rc;
[2]1145
[551]1146 bstrip(szBuffer);
1147 if (*szBuffer) {
1148 strcpy(szBuff, wa->szCurrentPath);
1149 if (szBuff[strlen(szBuff) - 1] != '\\')
1150 strcat(szBuff, "\\");
1151 strcat(szBuff, szBuffer);
1152 MakeFullName(szBuff);
1153 DosError(FERR_DISABLEHARDERR);
1154 hDir = HDIR_CREATE;
[766]1155 ulSearchCount = 1;
[551]1156 if (!IsRoot(szBuff)) {
[847]1157 rc = DosFindFirst(szBuff,
1158 &hDir,
1159 FILE_DIRECTORY |
1160 MUST_HAVE_DIRECTORY | FILE_READONLY |
1161 FILE_ARCHIVED | FILE_SYSTEM | FILE_HIDDEN,
1162 &findbuf,
1163 sizeof(FILEFINDBUF3),
1164 &ulSearchCount, FIL_STANDARD);
[551]1165 if (!rc)
1166 DosFindClose(hDir);
1167 }
1168 else {
1169 findbuf.attrFile = FILE_DIRECTORY;
1170 rc = 0;
1171 }
1172 if (!rc && (findbuf.attrFile & FILE_DIRECTORY)) {
1173 strcpy(wa->szCurrentPath, szBuff);
1174 WinSetDlgItemText(hwnd, WALK_PATH, wa->szCurrentPath);
1175 FillPathListBox(hwnd,
1176 WinWindowFromID(hwnd, WALK_DRIVELIST),
1177 WinWindowFromID(hwnd, WALK_DIRLIST),
1178 wa->szCurrentPath, FALSE);
1179 }
[242]1180 }
[551]1181 }
1182 else if (SHORT2FROMMP(mp1) == LN_SETFOCUS)
1183 WinSetDlgItemText(hwnd, WALK_HELP,
1184 GetPString(IDS_WALKDIRLISTHELPTEXT));
1185 else if (SHORT2FROMMP(mp1) == LN_KILLFOCUS)
1186 WinSetDlgItemText(hwnd, WALK_HELP,
1187 GetPString(IDS_WALKDEFAULTHELPTEXT));
1188 break;
1189 }
1190 return 0;
1191
1192 case WM_COMMAND:
[574]1193 wa = WinQueryWindowPtr(hwnd, QWL_USER);
[551]1194 if (!wa)
1195 WinDismissDlg(hwnd, 0);
1196 *szBuff = 0;
1197 WinQueryDlgItemText(hwnd, WALK_PATH, CCHMAXPATH, szBuff);
1198 bstrip(szBuff);
1199 while ((p = strchr(szBuff, '/')) != NULL)
1200 *p = '\\';
1201 while (strlen(szBuff) > 3 && szBuff[strlen(szBuff) - 1] == '\\')
1202 szBuff[strlen(szBuff) - 1] = 0;
1203 MakeFullName(szBuff);
[864]1204 if (*szBuff && stricmp(szBuff, wa->szCurrentPath) && SHORT1FROMMP(mp1) != DID_CANCEL) {
[551]1205 if (!SetDir(WinQueryWindow(WinQueryWindow(hwnd, QW_PARENT),
1206 QW_OWNER), hwnd, szBuff, 0))
1207 strcpy(wa->szCurrentPath, szBuff);
[865]1208 else
[242]1209 return 0;
[551]1210 }
1211 WinSetDlgItemText(hwnd, WALK_PATH, wa->szCurrentPath);
1212 switch (SHORT1FROMMP(mp1)) {
1213 case WALK_ADD:
1214 *szBuff = 0;
1215 WinQueryDlgItemText(hwnd, WALK_PATH, CCHMAXPATH, szBuff);
1216 bstrip(szBuff);
1217 while ((p = strchr(szBuff, '/')) != NULL)
1218 *p = '\\';
1219 if (*szBuff && !IsFile(szBuff)) {
1220 MakeFullName(szBuff);
[617]1221 add_udir(TRUE, szBuff);
1222 if (fUdirsChanged) {
[551]1223 WinSendDlgItemMsg(hwnd,
1224 WALK_USERLIST,
1225 LM_INSERTITEM,
1226 MPFROM2SHORT(LIT_SORTASCENDING, 0),
1227 MPFROMP(szBuff));
1228 wa->changed = 1;
1229 }
1230 }
1231 break;
[2]1232
[551]1233 case WALK_DELETE:
1234 *szBuff = 0;
1235 WinQueryDlgItemText(hwnd, WALK_PATH, CCHMAXPATH, szBuff);
1236 bstrip(szBuff);
1237 while ((p = strchr(szBuff, '/')) != NULL)
1238 *p = '\\';
1239 if (*szBuff && !IsFile(szBuff)) {
[242]1240 MakeFullName(szBuff);
[551]1241 sSelect = (SHORT) WinSendDlgItemMsg(hwnd,
1242 WALK_USERLIST,
1243 LM_SEARCHSTRING,
1244 MPFROM2SHORT(0, LIT_FIRST),
1245 MPFROMP(szBuff));
1246 if (sSelect >= 0) {
1247 WinSendDlgItemMsg(hwnd,
1248 WALK_USERLIST,
1249 LM_DELETEITEM, MPFROM2SHORT(sSelect, 0), MPVOID);
1250 remove_udir(szBuff);
1251 wa->changed = 1;
[242]1252 }
[551]1253 }
1254 break;
[2]1255
[551]1256 case DID_OK:
1257 if (*wa->szCurrentPath) {
1258 strcpy(wa->szReturnPath, wa->szCurrentPath);
1259 MakeValidDir(wa->szReturnPath);
1260 if (fAutoAddAllDirs)
1261 add_udir(FALSE, wa->szReturnPath);
1262 if (fChangeTarget) {
1263 strcpy(targetdir, wa->szReturnPath);
1264 PrfWriteProfileString(fmprof, appname, "Targetdir", targetdir);
1265 }
1266 }
[939]1267 {
[1077]1268 SWP swp;
1269 ULONG size = sizeof(SWP);
[939]1270
[1077]1271 WinQueryWindowPos(hwnd, &swp);
1272 PrfWriteProfileData(fmprof, FM3Str, "WalkDir.Position", (PVOID) &swp,
1273 size);
[939]1274 }
[551]1275 if (wa->changed)
1276 WinSendMsg(hwnd, UM_SETUP3, MPVOID, MPVOID);
1277 WinDismissDlg(hwnd, 1);
1278 break;
[2]1279
[551]1280 case IDM_HELP:
1281 if (hwndHelp)
1282 WinSendMsg(hwndHelp,
1283 HM_DISPLAY_HELP,
1284 MPFROM2SHORT(HELP_WALKEM, 0), MPFROMSHORT(HM_RESOURCEID));
1285 break;
[2]1286
[551]1287 case DID_CANCEL:
[939]1288 {
[1077]1289 SWP swp;
1290 ULONG size = sizeof(SWP);
[939]1291
[1077]1292 WinQueryWindowPos(hwnd, &swp);
1293 PrfWriteProfileData(fmprof, FM3Str, "WalkDir.Position", (PVOID) &swp,
1294 size);
[939]1295 }
[551]1296 if (wa->changed)
[1077]1297 WinSendMsg(hwnd, UM_SETUP3, MPVOID, MPVOID);
[1039]1298 free(wa);
[551]1299 WinDismissDlg(hwnd, 0);
1300 break;
1301 }
1302 return 0;
[2]1303
[551]1304 case WM_CLOSE:
[1077]1305 break;
[551]1306 }
1307 return WinDefDlgProc(hwnd, msg, mp1, mp2);
[2]1308}
1309
[242]1310MRESULT EXPENTRY WalkAllDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1311{
[551]1312 switch (msg) {
1313 case WM_INITDLG:
1314 return WalkDlgProc(hwnd, UM_SETUP2, mp1, mp2);
1315 }
1316 return WalkDlgProc(hwnd, msg, mp1, mp2);
[2]1317}
1318
[242]1319MRESULT EXPENTRY WalkCopyDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1320{
[551]1321 switch (msg) {
1322 case WM_INITDLG:
1323 WinSetWindowText(hwnd, GetPString(IDS_WALKCOPYDLGTEXT));
1324 return WalkDlgProc(hwnd, UM_SETUP2, mp1, mp2);
1325 }
1326 return WalkDlgProc(hwnd, msg, mp1, mp2);
[2]1327}
1328
[242]1329MRESULT EXPENTRY WalkMoveDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1330{
[551]1331 switch (msg) {
1332 case WM_INITDLG:
1333 WinSetWindowText(hwnd, GetPString(IDS_WALKMOVEDLGTEXT));
1334 return WalkDlgProc(hwnd, UM_SETUP2, mp1, mp2);
1335 }
1336 return WalkDlgProc(hwnd, msg, mp1, mp2);
[2]1337}
1338
[242]1339MRESULT EXPENTRY WalkExtractDlgProc(HWND hwnd, ULONG msg, MPARAM mp1,
1340 MPARAM mp2)
1341{
[551]1342 switch (msg) {
1343 case WM_INITDLG:
1344 WinSetWindowText(hwnd, GetPString(IDS_WALKEXTRACTDLGTEXT));
1345 return WalkDlgProc(hwnd, UM_SETUP2, mp1, mp2);
1346 }
1347 return WalkDlgProc(hwnd, msg, mp1, mp2);
[2]1348}
1349
[242]1350MRESULT EXPENTRY WalkTargetDlgProc(HWND hwnd, ULONG msg, MPARAM mp1,
1351 MPARAM mp2)
1352{
[551]1353 switch (msg) {
1354 case WM_INITDLG:
[242]1355 {
[551]1356 char s[CCHMAXPATH + 32];
[2]1357
[551]1358 sprintf(s,
1359 GetPString(IDS_WALKTARGETDLGTEXT),
1360 (*targetdir) ?
1361 NullStr :
1362 " (",
1363 (*targetdir) ?
1364 NullStr : GetPString(IDS_NONE), (*targetdir) ? NullStr : ")");
1365 WinSetWindowText(hwnd, s);
[242]1366 }
[551]1367 return WalkDlgProc(hwnd, UM_SETUP2, mp1, mp2);
1368 }
1369 return WalkDlgProc(hwnd, msg, mp1, mp2);
[2]1370}
1371
[242]1372MRESULT EXPENTRY WalkTwoDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1373{
[551]1374 WALK2 *wa;
1375 CHAR szBuff[CCHMAXPATH + 1], szBuffer[CCHMAXPATH + 1], *p;
1376 SHORT sSelect;
1377 static BOOL okay; /* avoid combobox selecting as filled */
[2]1378
[551]1379 switch (msg) {
1380 case UM_SETUP2:
1381 case WM_INITDLG:
1382 okay = FALSE;
1383 if (!mp2) {
1384 WinDismissDlg(hwnd, 0);
1385 break;
1386 }
[574]1387 WinSetWindowPtr(hwnd, QWL_USER, mp2);
[551]1388 wa = mp2;
[242]1389 {
[551]1390 PFNWP oldproc;
[2]1391
[551]1392 oldproc = WinSubclassWindow(WinWindowFromID(hwnd, WALK_PATH),
1393 (PFNWP) TextSubProc);
1394 if (oldproc)
1395 WinSetWindowPtr(WinWindowFromID(hwnd, WALK_PATH),
1396 QWL_USER, (PVOID) oldproc);
1397 oldproc = WinSubclassWindow(WinWindowFromID(hwnd, WALK2_PATH),
1398 (PFNWP) TextSubProc);
1399 if (oldproc)
1400 WinSetWindowPtr(WinWindowFromID(hwnd, WALK2_PATH),
1401 QWL_USER, (PVOID) oldproc);
1402 }
[939]1403 {
1404 SWP swp;
1405 ULONG size = sizeof(SWP);
1406
1407 PrfQueryProfileData(fmprof, FM3Str, "WalkDir2.Position", (PVOID) &swp, &size);
1408 WinSetWindowPos(hwnd,
[1077]1409 HWND_TOP,
1410 swp.x,
1411 swp.y,
1412 swp.cx,
1413 swp.cy,
1414 swp.fl);
[939]1415 }
[551]1416 if (!*wa->szCurrentPath1)
[1104]1417 strcpy(wa->szCurrentPath1, pFM2SaveDirectory);
[551]1418 MakeFullName(wa->szCurrentPath1);
1419 if (!*wa->szCurrentPath2)
[1104]1420 strcpy(wa->szCurrentPath2, pFM2SaveDirectory);
[551]1421 MakeFullName(wa->szCurrentPath2);
1422 WinSendDlgItemMsg(hwnd,
1423 WALK_PATH,
1424 EM_SETTEXTLIMIT, MPFROM2SHORT(CCHMAXPATH, 0), MPVOID);
1425 WinSetDlgItemText(hwnd, WALK_PATH, wa->szCurrentPath1);
1426 WinSendDlgItemMsg(hwnd, WALK2_PATH, EM_SETTEXTLIMIT,
1427 MPFROM2SHORT(CCHMAXPATH, 0), MPVOID);
1428 WinSetDlgItemText(hwnd, WALK2_PATH, wa->szCurrentPath2);
1429 FillPathListBox(hwnd,
1430 WinWindowFromID(hwnd, WALK_DRIVELIST),
1431 WinWindowFromID(hwnd, WALK_DIRLIST),
1432 wa->szCurrentPath1, FALSE);
1433 FillPathListBox(hwnd,
1434 WinWindowFromID(hwnd, WALK2_DRIVELIST),
1435 WinWindowFromID(hwnd, WALK2_DIRLIST),
1436 wa->szCurrentPath2, FALSE);
1437 if (!PostMsg(hwnd, UM_SETUP4, MPVOID, MPVOID))
1438 okay = TRUE;
1439 {
1440 MRESULT ret;
[2]1441
[551]1442 ret = WinDefDlgProc(hwnd, WM_INITDLG, mp1, mp2);
1443 WinSendMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
1444 WinInvalidateRect(WinWindowFromID(hwnd, WALK_PATH), NULL, TRUE);
1445 WinInvalidateRect(WinWindowFromID(hwnd, WALK2_PATH), NULL, TRUE);
1446 return ret;
1447 }
[2]1448
[551]1449 case UM_SETUP4:
1450 okay = TRUE;
1451 return 0;
[2]1452
[551]1453 case WM_PRESPARAMCHANGED:
1454 {
1455 ULONG AttrFound, AttrValue[64], cbRetLen;
[2]1456
[551]1457 cbRetLen = WinQueryPresParam(hwnd, (ULONG) mp1, 0, &AttrFound,
1458 (ULONG) sizeof(AttrValue), &AttrValue, 0);
1459 if (cbRetLen) {
1460 switch (AttrFound) {
1461 case PP_FONTNAMESIZE:
1462 PrfWriteProfileData(fmprof,
1463 appname,
1464 "WalkFont", (PVOID) AttrValue, cbRetLen);
1465 *WalkFont = 0;
1466 WalkFontSize = sizeof(WalkFont);
1467 WinInvalidateRect(WinWindowFromID(hwnd, WALK_PATH), NULL, TRUE);
1468 break;
[242]1469 }
[551]1470 }
1471 }
1472 break;
[2]1473
[551]1474 case UM_SETUP:
1475 {
1476 INT x;
1477 USHORT id[] = { WALK_PATH, WALK_DIRLIST,
1478 WALK2_PATH, WALK2_DIRLIST, 0
1479 };
[2]1480
[551]1481 if (*WalkFont ||
1482 (PrfQueryProfileData(fmprof,
1483 appname,
1484 "WalkFont",
1485 (PVOID) WalkFont,
1486 &WalkFontSize) && WalkFontSize)) {
1487 for (x = 0; id[x]; x++)
1488 WinSetPresParam(WinWindowFromID(hwnd, id[x]),
1489 PP_FONTNAMESIZE, WalkFontSize, (PVOID) WalkFont);
1490 }
1491 }
1492 return 0;
[2]1493
[551]1494 case UM_CONTROL:
1495 case WM_CONTROL:
[574]1496 wa = WinQueryWindowPtr(hwnd, QWL_USER);
[551]1497 if (SHORT1FROMMP(mp1) == WALK_DRIVELIST ||
1498 SHORT1FROMMP(mp1) == WALK_DIRLIST ||
1499 SHORT1FROMMP(mp1) == WALK2_DRIVELIST ||
1500 SHORT1FROMMP(mp1) == WALK2_DIRLIST) {
1501 sSelect = (USHORT) WinSendDlgItemMsg(hwnd,
1502 SHORT1FROMMP(mp1),
1503 LM_QUERYSELECTION, MPVOID, MPVOID);
1504 *szBuffer = 0;
1505 if (sSelect >= 0)
1506 WinSendDlgItemMsg(hwnd, SHORT1FROMMP(mp1), LM_QUERYITEMTEXT,
1507 MPFROM2SHORT(sSelect, CCHMAXPATH),
1508 MPFROMP(szBuffer));
1509 }
1510 switch (SHORT1FROMMP(mp1)) {
1511 case WALK_DRIVELIST:
1512 if (okay && *szBuffer && SHORT2FROMMP(mp1) == LN_ENTER) {
[2]1513
[551]1514 ULONG ulDirLen = CCHMAXPATH;
1515 APIRET rc;
[2]1516
[1321]1517 rc = DosQCurDir(toupper(*szBuffer) - '@', (PBYTE)&szBuff[3], &ulDirLen);
[551]1518 if (!rc) {
1519 strcpy(wa->szCurrentPath1, "C:\\");
1520 *wa->szCurrentPath1 = toupper(*szBuffer);
1521 WinSetDlgItemText(hwnd, WALK_PATH, wa->szCurrentPath1);
1522 FillPathListBox(hwnd,
1523 WinWindowFromID(hwnd, WALK_DRIVELIST),
1524 WinWindowFromID(hwnd, WALK_DIRLIST),
1525 wa->szCurrentPath1, FALSE);
1526 }
1527 }
1528 break;
[2]1529
[551]1530 case WALK_DIRLIST:
1531 if (okay && SHORT2FROMMP(mp1) == LN_ENTER) {
[2]1532
[551]1533 ULONG ulSearchCount;
[847]1534 FILEFINDBUF3 findbuf;
[551]1535 HDIR hDir;
1536 APIRET rc;
[2]1537
[551]1538 bstrip(szBuffer);
1539 if (*szBuffer) {
1540 strcpy(szBuff, wa->szCurrentPath1);
1541 if (szBuff[strlen(szBuff) - 1] != '\\')
1542 strcat(szBuff, "\\");
1543 strcat(szBuff, szBuffer);
1544 MakeFullName(szBuff);
1545 DosError(FERR_DISABLEHARDERR);
1546 hDir = HDIR_CREATE;
[766]1547 ulSearchCount = 1;
[551]1548 if (!IsRoot(szBuff)) {
[847]1549 rc = DosFindFirst(szBuff,
1550 &hDir,
1551 FILE_DIRECTORY |
1552 MUST_HAVE_DIRECTORY | FILE_READONLY |
1553 FILE_ARCHIVED | FILE_SYSTEM | FILE_HIDDEN,
1554 &findbuf,
1555 sizeof(FILEFINDBUF3),
1556 &ulSearchCount, FIL_STANDARD);
[551]1557 if (!rc)
1558 DosFindClose(hDir);
1559 }
1560 else {
1561 findbuf.attrFile = FILE_DIRECTORY;
1562 rc = 0;
1563 }
1564 if (!rc && (findbuf.attrFile & FILE_DIRECTORY)) {
1565 strcpy(wa->szCurrentPath1, szBuff);
1566 WinSetDlgItemText(hwnd, WALK_PATH, wa->szCurrentPath1);
1567 FillPathListBox(hwnd,
1568 WinWindowFromID(hwnd, WALK_DRIVELIST),
1569 WinWindowFromID(hwnd, WALK_DIRLIST),
1570 wa->szCurrentPath1, FALSE);
1571 }
1572 }
1573 }
1574 break;
[2]1575
[551]1576 case WALK2_DRIVELIST:
1577 if (okay && *szBuffer && SHORT2FROMMP(mp1) == LN_ENTER) {
[2]1578
[551]1579 ULONG ulDirLen = CCHMAXPATH;
1580 APIRET rc;
[2]1581
[1321]1582 rc = DosQCurDir(toupper(*szBuffer) - '@', (PBYTE)&szBuff[3], &ulDirLen);
[551]1583 if (!rc) {
1584 strcpy(wa->szCurrentPath2, "C:\\");
1585 *wa->szCurrentPath2 = toupper(*szBuffer);
1586 WinSetDlgItemText(hwnd, WALK2_PATH, wa->szCurrentPath2);
1587 FillPathListBox(hwnd,
1588 WinWindowFromID(hwnd, WALK2_DRIVELIST),
1589 WinWindowFromID(hwnd, WALK2_DIRLIST),
1590 wa->szCurrentPath2, FALSE);
1591 }
1592 }
1593 break;
[2]1594
[551]1595 case WALK2_DIRLIST:
1596 if (okay && SHORT2FROMMP(mp1) == LN_ENTER) {
[2]1597
[551]1598 ULONG ulSearchCount;
[847]1599 FILEFINDBUF3 findbuf;
[551]1600 HDIR hDir;
1601 APIRET rc;
[2]1602
[551]1603 bstrip(szBuffer);
1604 if (*szBuffer) {
1605 strcpy(szBuff, wa->szCurrentPath2);
1606 if (szBuff[strlen(szBuff) - 1] != '\\')
1607 strcat(szBuff, "\\");
1608 strcat(szBuff, szBuffer);
1609 MakeFullName(szBuff);
1610 DosError(FERR_DISABLEHARDERR);
1611 hDir = HDIR_CREATE;
[766]1612 ulSearchCount = 1;
[551]1613 if (!IsRoot(szBuff)) {
[847]1614 rc = DosFindFirst(szBuff,
1615 &hDir,
1616 FILE_DIRECTORY |
1617 MUST_HAVE_DIRECTORY | FILE_READONLY |
1618 FILE_ARCHIVED | FILE_SYSTEM | FILE_HIDDEN,
1619 &findbuf,
1620 sizeof(FILEFINDBUF3),
1621 &ulSearchCount, FIL_STANDARD);
[551]1622 if (!rc)
1623 DosFindClose(hDir);
1624 }
1625 else {
1626 findbuf.attrFile = FILE_DIRECTORY;
1627 rc = 0;
1628 }
1629 if (!rc && (findbuf.attrFile & FILE_DIRECTORY)) {
1630 strcpy(wa->szCurrentPath2, szBuff);
1631 WinSetDlgItemText(hwnd, WALK2_PATH, wa->szCurrentPath2);
1632 FillPathListBox(hwnd,
1633 WinWindowFromID(hwnd, WALK2_DRIVELIST),
1634 WinWindowFromID(hwnd, WALK2_DIRLIST),
1635 wa->szCurrentPath2, FALSE);
1636 }
[242]1637 }
[551]1638 }
1639 break;
1640 }
1641 return 0;
1642
1643 case WM_COMMAND:
[574]1644 wa = WinQueryWindowPtr(hwnd, QWL_USER);
[551]1645 if (!wa)
1646 WinDismissDlg(hwnd, 0);
1647 *szBuff = 0;
1648 WinQueryDlgItemText(hwnd, WALK_PATH, CCHMAXPATH, szBuff);
1649 bstrip(szBuff);
1650 while ((p = strchr(szBuff, '/')) != NULL)
1651 *p = '\\';
1652 while (strlen(szBuff) > 3 && szBuff[strlen(szBuff) - 1] == '\\')
1653 szBuff[strlen(szBuff) - 1] = 0;
1654 MakeFullName(szBuff);
[864]1655 if (*szBuff && stricmp(szBuff, wa->szCurrentPath1) && SHORT1FROMMP(mp1) != DID_CANCEL) {
[551]1656 if (!SetDir(WinQueryWindow(WinQueryWindow(hwnd, QW_PARENT),
1657 QW_OWNER), hwnd, szBuff, 0))
1658 strcpy(wa->szCurrentPath1, szBuff);
[865]1659 else
[242]1660 return 0;
[551]1661 }
1662 WinSetDlgItemText(hwnd, WALK_PATH, wa->szCurrentPath1);
1663 *szBuff = 0;
1664 WinQueryDlgItemText(hwnd, WALK2_PATH, CCHMAXPATH, szBuff);
1665 bstrip(szBuff);
1666 while ((p = strchr(szBuff, '/')) != NULL)
1667 *p = '\\';
1668 while (strlen(szBuff) > 3 && szBuff[strlen(szBuff) - 1] == '\\')
1669 szBuff[strlen(szBuff) - 1] = 0;
1670 MakeFullName(szBuff);
[864]1671 if (*szBuff && stricmp(szBuff, wa->szCurrentPath2) && SHORT1FROMMP(mp1) != DID_CANCEL) {
[551]1672 if (!SetDir(WinQueryWindow(WinQueryWindow(hwnd, QW_PARENT),
1673 QW_OWNER), hwnd, szBuff, 0))
1674 strcpy(wa->szCurrentPath2, szBuff);
[865]1675 else
[551]1676 return 0;
1677 }
1678 WinSetDlgItemText(hwnd, WALK2_PATH, wa->szCurrentPath2);
1679 switch (SHORT1FROMMP(mp1)) {
1680 case DID_OK:
[939]1681 {
1682 SWP swp;
1683 ULONG size = sizeof(SWP);
1684
1685 WinQueryWindowPos(hwnd, &swp);
1686 PrfWriteProfileData(fmprof, FM3Str, "WalkDir2.Position", (PVOID) &swp,
[1077]1687 size);
[939]1688 }
[551]1689 WinDismissDlg(hwnd, 1);
1690 break;
[2]1691
[551]1692 case IDM_HELP:
1693 if (hwndHelp)
1694 WinSendMsg(hwndHelp,
1695 HM_DISPLAY_HELP,
1696 MPFROM2SHORT(HELP_WALKEM2, 0), MPFROMSHORT(HM_RESOURCEID));
1697 break;
[2]1698
[551]1699 case DID_CANCEL:
[939]1700 {
1701 SWP swp;
1702 ULONG size = sizeof(SWP);
1703
1704 WinQueryWindowPos(hwnd, &swp);
1705 PrfWriteProfileData(fmprof, FM3Str, "WalkDir2.Position", (PVOID) &swp,
[1077]1706 size);
[939]1707 }
[551]1708 WinDismissDlg(hwnd, 0);
1709 break;
1710 }
1711 return 0;
[2]1712
[551]1713 case WM_CLOSE:
1714 break;
1715 }
1716 return WinDefDlgProc(hwnd, msg, mp1, mp2);
[2]1717}
1718
[242]1719MRESULT EXPENTRY WalkTwoCmpDlgProc(HWND hwnd, ULONG msg, MPARAM mp1,
1720 MPARAM mp2)
1721{
[551]1722 switch (msg) {
1723 case WM_INITDLG:
1724 WinSetWindowText(hwnd, GetPString(IDS_WALKCOMPAREDLGTEXT));
1725 return WalkTwoDlgProc(hwnd, UM_SETUP2, mp1, mp2);
1726 }
1727 return WalkTwoDlgProc(hwnd, msg, mp1, mp2);
[2]1728}
1729
[242]1730MRESULT EXPENTRY WalkTwoSetDlgProc(HWND hwnd, ULONG msg, MPARAM mp1,
1731 MPARAM mp2)
1732{
[551]1733 switch (msg) {
1734 case WM_INITDLG:
1735 WinSetWindowText(hwnd, GetPString(IDS_WALKSETDIRSDLGTEXT));
1736 return WalkTwoDlgProc(hwnd, UM_SETUP2, mp1, mp2);
1737 }
1738 return WalkTwoDlgProc(hwnd, msg, mp1, mp2);
[2]1739}
[794]1740
1741#pragma alloc_text(WALKER,FillPathListBox,WalkDlgProc,TextSubProc)
1742#pragma alloc_text(WALKER,WalkAllDlgProc,WalkCopyDlgProc)
1743#pragma alloc_text(WALKER,WalkMoveDlgProc,WalkExtractDlgProc,WalkTargetDlgProc)
1744#pragma alloc_text(WALK2,WalkTwoDlgProc,WalkTwoCmpDlgProc,WalkTwoSetDlgProc)
1745#pragma alloc_text(UDIRS,add_udir,remove_udir,remove_ldir,load_udirs)
[807]1746#pragma alloc_text(UDIRS,save_udirs,load_setups,save_setups,add_setups)
[794]1747#pragma alloc_text(UDIRS,remove_setup)
Note: See TracBrowser for help on using the repository browser.