_&$~ UNDEL.BCKt UNDEL.BCK!BACKUP/LOG UNDEL.* UNDEL.BCK/SAVE TK91 q*V5.4  _NDONE$DUA0: V5.4 ~  $*[FRANCE_1991.VAXF91B.VMS]UNDEL.COM;1+,g./ 4Nz-0123KPWO56 57O#8#*k9GHJN @  $ Type SYS$INPUT:- Rcupration de fichiers effacs par erreur? La documentation ncessaire l'utilisation de cette procdure; est contenue dans la procdure sous forme de commentaires.$!E$! Cette procdure appelle le programme UNDEL qui permet de rcuprer9$! un ou des fichier(s) effacs par erreur, condition:$!;$! - que leur place physique n'ait pas t rutilise 7$! par la cration ou l'extension d'autres fichiers.D$! - que l'utilisateur de ce programme ait une grande confiance$! en son auteur.$! B$! Cette procdure ne met en danger ni la structure du disque,J$! ni les autres fichiers, la condition d'utiliser ANALYZE correctement,K$! en particulier dans le cas ou l'on trouve des erreurs de type MULTALLOC.=$! Dans ce cas, une action irrflchie risque de faire perdre/$! tout ou parties d'autres fichiers du disque.$!K$! On trouvera dans UNDEL.MAR la description de la mthode de rcupration.$!/$ PREVDIR = f$logical("SYS$DISK")+f$directory() $ PREVPRIVS = f$setprv("BYPASS"),$ If f$privilege("BYPASS") Then Goto OK_PRIV3$ Write SYS$OUTPUT "On doit avoir BYPASS ou SETPRV"$ Exit $ OK_PRIV:$!*$! Mise par dfaut sur le disque concern.$!D$ Inquire /Nopunct DISQUE "Quel est le disque utiliser (ddcu:) ? "$ DISQUE = DISQUE - ":" + ":"$ Set Default 'DISQUE'[000000]$ Assign 'DISQUE' DISK$!&$! Nom du ou des fichiers rcuprer.3$! Si un nom de fichier est "nom.typ;v", on pourra:$!D$! - donner seulement "nom", on tentera alors de rcuprer "nom.*;*"7$! - donner "nom.typ", on recherchera alors "nom.typ;*"$! - donner "nom.typ;v"$! $ DEMANDE:A$ Inquire /Nopunct FILE "Nom du ou des fichier(s) rcuprer : ""$ If FILE.eqs."" Then Goto DEMANDE$ L = 'f$length(FILE)$ I = 'f$locate(".",FILE)"$ If I.ne.L Then Goto CHERCHE_VERS$ FILE:="''FILE'." $ Goto RUN$ CHERCHE_VERS:$ I = 'f$locate(";",FILE)!$ If I.eq.L Then FILE:="''FILE';"$ RUN:$ On Warning Then Goto SORTIE$ Run SYS_UTILS:UNDEL$!J$! Le programme UNDEL, s'il a trouv des fichiers rcuprables, a "rpar"F$! leur header. Il reste remettre en ordre la bitmap du disque et L$! recataloguer le(s) fichier(s) dans la directory voulue. Pour cela, on va*$! faire passer ANALYZE /DISK_STRUCTURE. $!G$! Parmi les erreurs ventuelles possibles trouves par cet utilitaire,$! la suivante est normale:$!.$! LOSTHEADER (file not found in a directory).$!I$! Tous les fichiers recuperes seront dans ce cas. Il seront alors entrs $! dans la directory [SYSLOST].$!)$ Assign /User_mode SYS$COMMAND SYS$INPUT)$ Analyze /Disk /Repair /Confirm 'DISQUE' $ SORTIE:$!I$! Ici, en principe, les fichiers rcuprs sont dans [SYSLOST]. Il resteN$! faire un ou plusieurs RENAME pour les re-cataloguer dans les directories$! convenables.$!$ I:='f$setprv(PREVPRIVS)$ Set Default 'PREVDIR'$ Exit$*[FRANCE_1991.VAXF91B.VMS]UNDEL.DOC;1+,h./ 4Mx-0123KPWO56`"7 #89GHJN |@ c program UNDELc -----c%c Undelete a file on a FILES-11 diskcMc --------------------------------------------------------------------------cDc Handles disks with any cluster size, and files with any number ofEc extension headers. Use with caution only when you REALLY need it; Bc a backup copy is always preferable if you have one. If the file>c is really vital, back the disk up before using UNDEL on it.c@c Define $ UNDEL=="$disk:[directory]UNDEL.EXE" in SYSLOGIN etc.cMc Use: $ UNDEL disk:filename ! puts it into original directoryKc $ UNDEL disk:[dir]filename ! puts it in [dir] if it existsc!c Disk must be mounted Files-11.c$c IF THIS PROGRAM SHOULD FALL OVER:cFc $ ANALYZE/DISK/REPAIR the disk afterwards if this program does not Ic recover the file or crashes for any reason without finishing normally.Ic You will probably get the file you wanted in the [SYSLOST] directory, Kc with possible multiply allocated blocks. If there are multiply allocated<c blocks, copy the file to another disk and delete it, thenKc ANALYZE/DISK/REPAIR the disk again to clean it up. You will have to editIc or otherwise clean up the junk in the file in this case. If not, then c the file and disk are OK. cKc ------------------------------------------------------------------------$*[FRANCE_1991.VAXF91B.VMS]UNDEL.EXE;1+,j. / 4 -0123 KPWO 56A7@c#89GHJN @ 0DX0205(]}h UNDEL0]05-05  ?! LIBRTL_001@@DISK a ete recupere $V7Ce fichier est irrecuperable car partiellement realloueP"FilePUNDEL$MULTALLOC :Fichier partiellement realloue, mais recupere neanmoins...< |~:(P|~|~|~<8~<~ 0P1jv|~|~P @, }F[>0  ЏP1q</ +! |~<~ݏ" xP1ď1P `}|vi\01kZ>JkZP@j 1lP)_j1"![Y0Ў[g5L/P?1)<P P0)j10[%Y0LЎ[ʏ4ЏPQ@aQPQ|~NݏB|~<0~<~ tP /QQ QQ`<PP0:1^(j1(Џ PЏPP0^; La procedure de commande UNDEL.COM fait tout ce qu'il faut.;--; Auteur : J.Y. COLLOT IGN _ 1983,84,85;; Modifications :; -------------K; 1 - 01/84 Ajout d'un QIO ACP_CONTROL!IO$M_DISM pour forcer l'ecriture'; par l'ACP des headers caches.;J; 2 - 02/84 Ajout de QIOs LOCK et UNLOCK pour interdire la creation et7; l'extension de nouveaux fichiers pendant l'execution;I; 3 - 01/85 Traitement de la bitmap du disque, et verification que leJ; fichier est vraiment recuperable (les blocs n'ont pas ete ; realloues).;J; 4 - 01/85 Prise en compte des fichiers ayant des headers d'extension;<; 5 - 04/86 Correction sortie systematiquement en erreur;L; 6 - 04/86 Ajout du test (undocumented) sur le symbole UNDEL$MULTALLOC.H; Dans ce cas, on recupere meme les fichiers partiellementB; realloues. (Beware the MULTALLOCs and INCMARKFREEs !!! );0 $FIBDEF ; Structure du File Information Block+ $FH2DEF ; Structure de File Header ODS-2 $FM2DEF ; Map pointers* $HM2DEF ; Structure de Home Block ODS-2 $SECDEF ; Pour $CRMPSCcr=13lf=10; .PSECT $DATA,WRT,NOEXE,LONG2; Variables utilisees pour les I/Os sur INDEXF.SYSFibd: .long FIB$C_LENGTH .address Fib Fib: .blkl 5 .word 0Fib_CtrlFunc: .word .blkl 6Disk: .ascid 'DISK' Canal: .word Iosb: .blkw 4 Status: .LONGClusterSize: .long;; Autres variables;B; Message d'auto-satisfaction d'avoir retrouve un fichier que l'on; croyait perdu...Message: .byte ^A' '[20] .ascii ' a ete recupere'(MessageDescr: .long MessageDescr-Message .address Message Reallocated:A .ascid 'Ce fichier est irrecuperable car partiellement realloue'Inadr: .blkl 2BmapAdr: .blkl 2FmapAdr: .blkl 2 Chan: .word Ok: .byte 0File: .blkb 80 .align long;0BmapFab: $fab fnm=<[000000]BITMAP.SYS>,fac=PUT,- fop=CBlocLu: .blkb 512 ; Cette zone recevra le Home block et les Headers0NumHead: .long ; VBN du header en cours d'etudeNumSave: .long9Header1: .long ; VBN du header de INDEXF.SYS (FID=1,1,0)IFreeHead: .long ; No du bit de la partie de bitmap etudiee correspondant ; a un header libreCFileId: .long ; File ID du fichier dont le header est dans BlocLu=NumBitmap: .long ; VBN du bloc de bit map des headers etudie*MapSize: .long ; Nb de blocs de la bitmapFFirstFid: .long ; VBN du header correspondant au 1er bit de la partie ; de bitmap en cours d'etude0Symbol: .ascid 'File' ; Nom du fichier chercheLongNam:.long 80 .address File Trouve: .byte undoc_symbol: .ascid 'UNDEL$MULTALLOC' undoc_trad: .ascid ' 'undoc_message:D .ascid 'Fichier partiellement realloue, mais recupere neanmoins...';$ .psect $CODE,pic,shr,exe,nowrt,long% .entry Undel,^M;>; Ouverture du fichier INDEXF.SYS avec des QIO interface ACP3 $assign_s devnam=Disk,chan=Canal ; ouverture Canal+; Force mise a jour du disque par l'ACP/XQP> $qiow_s chan=Canal,func=#IO$_ACPCONTROL!IO$M_DMOUNT,iosb=Iosb clrw Fib_CtrlFunc bsbw Lock_Volume4; Mapping du fichier BITMAP.SYS en memoire virtuelle; Open du fichier $open fab=BmapFab blbs R0,1$ brw Erreur61$: movw BmapFab+FAB$L_STV,Chan ;Store Channel number(; Mapping du fichier en section privee) $crmpsc_s inadr=Inadr, retadr=BmapAdr, -" flags=#SEC$M_EXPREG!SEC$M_WRT,- chan=Chan blbs r0,2$ brw Erreur2$: moval Fib,R0? movl #FIB$M_WRITE,FIB$L_ACCTL(R0) ; autorisation d'ecriture+ movw #1,FIB$W_FID(R0) ; File ID = (1,1,0), movw #1,FIB$W_FID+2(R0) ; pour INDEXF.SYSB $qiow_s chan=Canal,func=#IO$_ACCESS!IO$M_ACCESS,iosb=Iosb,p1=Fibd blbs R0,3$ brw Erreur3$: blbs Iosb,4$ movzwl Iosb,R0 brw Erreur;4$: clrb Trouve-; Recuperation du nom du fichier a retrouver. pushal LongNam pushaq LongNam pushaq Symbol calls #3,G^Lib$Get_Symbol blbc R0,5$ tstl LongNam bneq 6$; Exit si ^Z ou 5$: $exit_s; Complete avec des blancs&6$: movc5 #20,File,#^A' ',LongNam,File;Read_Home_Block: movab BlocLu,R114 movl #2,NumHead ; Lecture du bloc 2 --> Home Block bsbw read_header0 cmpb HM2$B_STRUCLEV(R11),#2 ; Structure ODS-2 ? beql 1$ ; Oui) movl #SS$_FileSTRUCT,R0 ; Si non, Erreur brw Erreur)1$: movzwl hm2$w_cluster(r11),ClusterSizeB movw HM2$W_IBMAPVBN(R11),NumBitmap ; VBN du 1er bloc de la bitmap8 movw HM2$W_IBMAPSIZE(R11),MapSize ; Taille de la bitmap addl3 NumBitmap,MapSize,Header1$ decl Header1 ; VBN du 1er header2 movw #1,FirstFid ; File Id du 1er header libre 7; Mapping de la bitmap des headers en memoire virtuelle(; Mapping du fichier en section privee) $crmpsc_s inadr=Inadr, retadr=FmapAdr, -" flags=#SEC$M_EXPREG!SEC$M_WRT,-* chan=Canal,vbn=NumBitmap,pagcnt=MapSize blbs r0,2$ brw Erreur@2$: mull2 #512*8,MapSize ; Nb de bits dans la bitmap des headers mnegl #1,FreeHead;Recherche_header_libre: incl FreeHead@2$: cmpl FreeHead,MapSize ; Si on a depasse la taille de bitmap, bleq 1$ ; c'est fini brw fini1$: movl FmapAdr,r0= ffc FreeHead,#32,(r0),FreeHead ; recherche d'un header libre beql 2$ ; Rien Trouve ...;/; On a Trouve le numero d'un header non utilise ; Lisons le/ addl3 FirstFid,FreeHead,FileId ; Calcul du FID> addl3 FileId,Header1,NumHead ; Calcul du VBN dans INDEXF.SYS bsbw Read_HeaderO; Si Iosb n'est pas correct, c'est qu'on a depasse le nombre de blocs alloues.H; ( il n'est pas certain que ce soit possible, mais ca ne coute rien de; verifier...) blbs Iosb,3$ brw Fini;$3$: movzbl FH2$B_IDOFFSET(R11),R10 9 movaw (R11)[R10],R10 ; R10 pointe sur le nom du fichier@; On verifie que tous les caracteres du champ "nom du fichier" J; sont imprimables. Sinon,ce header n'a jamais ete utilise, et on a Fini.Verification_Nom: movl #19,R01$: cmpb (R10)[R0],#^A' ' bgeq 2$2 brw Fini ; Au premier non imprimable,c'est Fini2$: sobgeq R0,1$;9 cmpc3 LongNam,File,(R10) ; S'agit-il du fichier cherche? beql Header_Trouve2 brw Recherche_Header_Libre ; Sinon, on continue;Header_Trouve:E; Etudions ce header, et eventuellement les headers d'extension qui; lui sont chaines... movl NumHead,NumSave;C; Avant de reparer ce header, on va voir dans la bitmap du disqueD; si,par hasard, certains des blocs n'ont pas ete realloues par unH; autre fichier. Si oui, on va simplement abandonner tout espoir de ; recuperation. pushl R11 moval Verif_Bitmap,r9 bsbw Etude_Bitmap popl R110 tstb Ok ; Y-a-t-il au moins 1 bloc realloue ? beql 1$ ; non !; 2$: ; Partiellement realloue7 pushaq undoc_trad ; Le symbole UNDEL$MULTALLOC est-il pushaq undoc_symbol ; connu ?1 calls #2,g^lib$get_symbol ; Si non, on abandonne blbc r0,10$7 pushaq undoc_message ; Si oui, on recupere quand meme, calls #1,g^lib$put_output ; a dieu vat... brb 1$;/10$: pushaq Reallocated ; non recuperable .... calls #1,g^Lib$Put_Output2 brw Recherche_Header_Libre ; passons au suivant;1$:B movzwl FH2$W_EXT_FID(R11),R0 ; FID eventuel du header d'extension; beql Corrige_Header ; y'a pas ou plus d'extensions.: addl3 R0,Header1,NumHead ; Calcul du VBN dans INDEXF.SYS bsbw Read_Header& cmpc3 LongNam,File,(R10) ; meme nom ? bneq 2$ brw Header_Trouve;Corrige_Header:'; Relecture du 1er header si necessaire cmpl NumHead,NumSave beql Recons_Header movl NumSave,NumHead bsbw Read_HeaderRecons_Header:4; On sait maintenant que le fichier est recuperable.?; Dans un premier temps,on va reconstruire la bitmap du disque,,; en marquant alloues les clusters concernes pushl R11 moval Recons_Bitmap,r9 bsbw Etude_Bitmap popl R11;#; Il reste a reconstruire le header;< movw FileId,FH2$W_FID(R11) ; On remet le FID a sa placeB bicl2 #FH2$M_MARKDEL,FH2$L_FILECHAR(R11) ; Suppression du bit qui ; marque le fichier efface$ movl #254,R0 ; Calcul de checksum clrl R11$: addw BlocLu[R0],R1 sobgeq R0,1$= movw R1,FH2$W_CHECKSUM(R11) ; Et positionnement du checksum;; On reecrit le headerF $qiow_s chan=Canal,func=#IO$_WRITEVBLK,p1=BlocLu,p2=#512,p3=NumHead,- iosb=Iosb;-; On marque ce header utilise dans la bitmap movl FmapAdr,R0 addl3 HeadeR1,FirstFid,R1 subl3 R1,NumHead,R1 bbss R1,(R0),2$2$:A; Et on va reconstruire de meme les eventuels headers d'extensionB movzwl FH2$W_EXT_FID(R11),R0 ; FID eventuel du header d'extension4 beql Recupere ; y'a pas ou plus d'extensions.< addl3 R0,HeadeR1,NumHead ; Calcul du VBN dans INDEXF.SYS bsbw Read_Header brw Recons_Header; Recupere:; un Message sur le terminal incb trouve movc3 #20,(R10),Message pushaq MessageDescr calls #1,G^Lib$Put_Output;H brw Recherche_Header_Libre ; Retournons chercher d'autres fichiersFini: movl #SS$_NOSUCHFile,R0 tstb Trouve beql Erreur movl #SS$_NORMAL,R0Erreur: movl R0,Status bsbw Unlock_Volume $dassgn_s chan=Canal $exit_s Status; Verif_Bitmap:E; A l'entree de ce sous-programme, R2 contient le nb de blocs alloues; et R3 le LBN du premier bloc pushl R11 movl BmapAdr,R112 addl2 #512,R11 ; La bitmap demarre au second bloc& divl2 ClusterSize,R2 ; nb de clusters. divl2 ClusterSize,R3 ; Logical Cluster Number1$: bbs R3,(R11),2$ movb #1,Ok 2$: incl R3 sobgeq R2,1$ popl R11 rsb;Recons_Bitmap:E; A l'entree de ce sous-programme, R2 contient le nb de blocs alloues; et R3 le LBN du premier bloc pushl R11 movl BmapAdr,R112 addl2 #512,R11 ; La bitmap demarre au second bloc& divl2 ClusterSize,R2 ; nb de clusters. divl2 ClusterSize,R3 ; Logical Cluster Number1$: bbsc R3,(R11),2$ 2$: incl R3 sobgeq R2,1$ popl R11 rsb; Etude_Bitmap: movzbl FH2$B_MPOFFSET(R11),R0 addl2 R0,R0 9 movzbl FH2$B_MAP_INUSE(R11),R1 ; Nb de Words de map ptrs bneq 1$ ; si 0, fichier vide rsb+1$: addl2 R1,R1 ; nb de bytes de map ptrs/ addl2 R0,R11 ; R11 pointe sur le 1er Map Ptr" clrb Ok ; a priori, tout est bonEtude_Map_pointer:7 extzv #FM2$V_FORMAT,#FM2$S_FORMAT,FM2$W_WORD0(R11),R0  caseb R0,#0,#3$1$: .word 2$-1$ ; Placement control .word 3$-1$ ; Format 1 .word 4$-1$ ; Format 2 .word 5$-1$ ; Format 3#2$: ; Placement Control (ignore) subl2 #FM2$C_LENGTH0,R1 addl2 #FM2$C_LENGTH0,R11 brb Pointer_Suivant3$: ; Format 1$ movzbl FM2$B_COUNT1(R11),R2 ; Count8 extzv #FM2$V_HIGHLBN,#FM2$S_HIGHLBN,FM2$W_WORD0(R11),R3 ashl #16,R3,R3 movw FM2$W_LOWLBN(R11),R3 ; LBN subl2 #FM2$C_LENGTH1,R1 addl2 #FM2$C_LENGTH1,R11 jsb (R9) brb Pointer_Suivant4$: ; Format 2D extzv #FM2$V_COUNT2,#FM2$S_COUNT2,FM2$W_WORD0(R11),R2 ; Block count movl FM2$L_LBN2(R11),R3 ; LBN jsb (R9) subl2 #FM2$C_LENGTH2,R1 addl2 #FM2$C_LENGTH2,R11 brb Pointer_Suivant5$: ; Format 36 EXTZV #FM2$V_COUNT2,#FM2$S_COUNT2,FM2$W_WORD0(R11),R2 ashl #16,R2,R2* movw FM2$W_LOWCOUNT(R11),R2 ; Block count movl FM2$L_LBN3(R11),R3 ; LBN jsb (R9) subl2 #FM2$C_LENGTH3,R1 addl2 #FM2$C_LENGTH3,R11Pointer_Suivant: tstl R1 beql 1$ brw Etude_Map_Pointer1$: rsb; Read_Header:E $qiow_s chan=Canal,func=#IO$_READVBLK,p1=BlocLu,p2=#512,p3=NumHead,- iosb=Iosb rsb; Lock_Volume:" movw #FIB$C_LOCK_VOL,Fib_CtrlFunc: $qiow_s chan=Canal,func=#IO$_ACPCONTROL,iosb=Iosb,p1=Fibd rsb;Unlock_Volume:" movw #FIB$C_UNLK_VOL,Fib_CtrlFunc: $qiow_s chan=Canal,func=#IO$_ACPCONTROL,iosb=Iosb,p1=Fibd rsb; .end Undel~ UNDEL.BCK+  UNDEL.BCK!BACKUP/LOG UNDEL.* UNDEL.BCK/SAVE TK91 q*V5.4  _NDONE$DUA0: V5.4 ~  $*[FRANCE_1991.VAXF91B.VMS]UNDEL.COM;1+,g./ 4Nz-0123KPWO56 57O#8#*k9GHJN @  $ Type SYS$INPUT:- Rcupration de fichiers effacs par erreur? La documentation ncessaire l'utilisation de cette procdure; est contenue dans la procdure sous forme de commentaires.$!E$! Cette procdure appelle le programme UNDEL qui permet de rcuprer9$! un ou des fichier(s) effacs par erreur, condition:$!;$! - que leur place physique n'ait pas t rutilise 7$! par la cration ou l'extension d'autres fichiers.D$! - que l'utilisateur de ce programme ait une grande confiance$! en son auteur.$! B$! Cette procdure ne met en danger ni la structure du disque,J$! ni les autres fichiers, la condition d'utiliser ANALYZE correctement,K$! en particulier dans le cas ou l'on trouve des erreurs de type MULTALLOC.=$! Dans ce cas, une action irrflchie risque de faire perdre/$! tout ou parties d'autres fichiers du disque.$!K$! On trouvera dans UNDEL.MAR la description de la mthode de rcupration.$!/$ PREVDIR = f$logical("SYS$DISK")+f$directory() $ PREVPRIVS = f$setprv("BYPASS"),$ If f$privilege("BYPASS") Then Goto OK_PRIV3$ Write SYS$OUTPUT "On doit avoir BYPASS ou SETPRV"$ Exit $ OK_PRIV:$!*$! Mise par dfaut sur le disque concern.$!D$ Inquire /Nopunct DISQUE "Quel est le disque utiliser (ddcu:) ? "$ DISQUE = DISQUE - ":" + ":"$ Set Default 'DISQUE'[000000]$ Assign 'DISQUE' DISK$!&$! Nom du ou des fichiers rcuprer.3$! Si un nom de fichier est "nom.typ;v", on pourra:$!D$! - donner seulement "nom", on tentera alors de rcuprer "nom.*;*"7$! - donner "nom.typ", on recherchera alors "nom.typ;*"$! - donner "nom.typ;v"$! $ DEMANDE:A$ Inquire /Nopunct FILE "Nom du ou des fichier(s) rcuprer : ""$ If FILE.eqs."" Then Goto DEMANDE$ L = 'f$length(FILE)$ I = 'f$locate(".",FILE)"$ If I.ne.L Then Goto CHERCHE_VERS$ FILE:="''FILE'." $ Goto RUN$ CHERCHE_VERS:$ I = 'f$locate(";",FILE)!$ If I.eq.L Then FILE:="''FILE';"$ RUN:$ On Warning Then Goto SORTIE$ Run SYS_UTILS:UNDEL$!J$! Le programme UNDEL, s'il a trouv des fichiers rcuprables, a "rpar"F$! leur header. Il reste remettre en ordre la bitmap du disque et L$! recataloguer le(s) fichier(s) dans la directory voulue. Pour cela, on va*$! faire passer ANALYZE /DISK_STRUCTURE. $!G$! Parmi les erreurs ventuelles possibles trouves par cet utilitaire,$! la suivante est normale:$!.$! LOSTHEADER (file not found in a directory).$!I$! Tous les fichiers recuperes seront dans ce cas. Il seront alors entrs $! dans la directory [SYSLOST].$!)$ Assign /User_mode SYS$COMMAND SYS$INPUT)$ Analyze /Disk /Repair /Confirm 'DISQUE' $ SORTIE:$!I$! Ici, en principe, les fichiers rcuprs sont dans [SYSLOST]. Il resteN$! faire un ou plusieurs RENAME pour les re-cataloguer dans les directories$! convenables.$!$ I:='f$setprv(PREVPRIVS)$ Set Default 'PREVDIR'$ Exit$*[FRANCE_1991.VAXF91B.VMS]UNDEL.DOC;1+,h./ 4Mx-0123KPWO56`"7 #89GHJN |@ c program UNDELc -----c%c Undelete a file on a FILES-11 diskcMc --------------------------------------------------------------------------cDc Handles disks with any cluster size, and files with any number ofEc extension headers. Use with caution only when you REALLY need it; Bc a backup copy is always preferable if you have one. If the file>c is really vital, back the disk up before using UNDEL on it.c@c Define $ UNDEL=="$disk:[directory]UNDEL.EXE" in SYSLOGIN etc.cMc Use: $ UNDEL disk:filename ! puts it into original directoryKc $ UNDEL disk:[dir]filename ! puts it in [dir] if it existsc!c Disk must be mounted Files-11.c$c IF THIS PROGRAM SHOULD FALL OVER:cFc $ ANALYZE/DISK/REPAIR the disk afterwards if this program does not Ic recover the file or crashes for any reason without finishing normally.Ic You will probably get the file you wanted in the [SYSLOST] directory, Kc with possible multiply allocated blocks. If there are multiply allocated<c blocks, copy the file to another disk and delete it, thenKc ANALYZE/DISK/REPAIR the disk again to clean it up. You will have to editIc or otherwise clean up the junk in the file in this case. If not, then c the file and disk are OK. cKc ------------------------------------------------------------------------$*[FRANCE_1991.VAXF91B.VMS]UNDEL.EXE;1+,j. / 4 -0123 KPWO 56A7@c#89GHJN @ 0DX0205(]}h UNDEL0]05-05  ?! LIBRTL_001@@DISK a ete recupere $V7Ce fichier est irrecuperable car partiellement realloueP"FilePUNDEL$MULTALLOC :Fichier partiellement realloue, mais recupere neanmoins...< |~:(P|~|~|~<8~<~ 0P1jv|~|~P @, }F[>0  ЏP1q</ +! |~<~ݏ" xP1ď1P `}|vi\01kZ>JkZP@j 1lP)_j1"![Y0Ў[g5L/P?1)<P P0)j10[%Y0LЎ[ʏ4ЏPQ@aQPQ|~NݏB|~<0~<~ tP /QQ QQ`<PP0:1^(j1(Џ PЏPP0^; La procedure de commande UNDEL.COM fait tout ce qu'il faut.;--; Auteur : J.Y. COLLOT IGN _ 1983,84,85;; Modifications :; -------------K; 1 - 01/84 Ajout d'un QIO ACP_CONTROL!IO$M_DISM pour forcer l'ecriture'; par l'ACP des headers caches.;J; 2 - 02/84 Ajout de QIOs LOCK et UNLOCK pour interdire la creation et7; l'extension de nouveaux fichiers pendant l'execution;I; 3 - 01/85 Traitement de la bitmap du disque, et verification que leJ; fichier est vraiment recuperable (les blocs n'ont pas ete ; realloues).;J; 4 - 01/85 Prise en compte des fichiers ayant des headers d'extension;<; 5 - 04/86 Correction sortie systematiquement en erreur;L; 6 - 04/86 Ajout du test (undocumented) sur le symbole UNDEL$MULTALLOC.H; Dans ce cas, on recupere meme les fichiers partiellementB; realloues. (Beware the MULTALLOCs and INCMARKFREEs !!! );0 $FIBDEF ; Structure du File Information Block+ $FH2DEF ; Structure de File Header ODS-2 $FM2DEF ; Map pointers* $HM2DEF ; Structure de Home Block ODS-2 $SECDEF ; Pour $CRMPSCcr=13lf=10; .PSECT $DATA,WRT,NOEXE,LONG2; Variables utilisees pour les I/Os sur INDEXF.SYSFibd: .long FIB$C_LENGTH .address Fib Fib: .blkl 5 .word 0Fib_CtrlFunc: .word .blkl 6Disk: .ascid 'DISK' Canal: .word Iosb: .blkw 4 Status: .LONGClusterSize: .long;; Autres variables;B; Message d'auto-satisfaction d'avoir retrouve un fichier que l'on; croyait perdu...Message: .byte ^A' '[20] .ascii ' a ete recupere'(MessageDescr: .long MessageDescr-Message .address Message Reallocated:A .ascid 'Ce fichier est irrecuperable car partiellement realloue'Inadr: .blkl 2BmapAdr: .blkl 2FmapAdr: .blkl 2 Chan: .word Ok: .byte 0File: .blkb 80 .align long;0BmapFab: $fab fnm=<[000000]BITMAP.SYS>,fac=PUT,- fop=CBlocLu: .blkb 512 ; Cette zone recevra le Home block et les Headers0NumHead: .long ; VBN du header en cours d'etudeNumSave: .long9Header1: .long ; VBN du header de INDEXF.SYS (FID=1,1,0)IFreeHead: .long ; No du bit de la partie de bitmap etudiee correspondant ; a un header libreCFileId: .long ; File ID du fichier dont le header est dans BlocLu=NumBitmap: .long ; VBN du bloc de bit map des headers etudie*MapSize: .long ; Nb de blocs de la bitmapFFirstFid: .long ; VBN du header correspondant au 1er bit de la partie ; de bitmap en cours d'etude0Symbol: .ascid 'File' ; Nom du fichier chercheLongNam:.long 80 .address File Trouve: .byte undoc_symbol: .ascid 'UNDEL$MULTALLOC' undoc_trad: .ascid ' 'undoc_message:D .ascid 'Fichier partiellement realloue, mais recupere neanmoins...';$ .psect $CODE,pic,shr,exe,nowrt,long% .entry Undel,^M;>; Ouverture du fichier INDEXF.SYS avec des QIO interface ACP3 $assign_s devnam=Disk,chan=Canal ; ouverture Canal+; Force mise a jour du disque par l'ACP/XQP> $qiow_s chan=Canal,func=#IO$_ACPCONTROL!IO$M_DMOUNT,iosb=Iosb clrw Fib_CtrlFunc bsbw Lock_Volume4; Mapping du fichier BITMAP.SYS en memoire virtuelle; Open du fichier $open fab=BmapFab blbs R0,1$ brw Erreur61$: movw BmapFab+FAB$L_STV,Chan ;Store Channel number(; Mapping du fichier en section privee) $crmpsc_s inadr=Inadr, retadr=BmapAdr, -" flags=#SEC$M_EXPREG!SEC$M_WRT,- chan=Chan blbs r0,2$ brw Erreur2$: moval Fib,R0? movl #FIB$M_WRITE,FIB$L_ACCTL(R0) ; autorisation d'ecriture+ movw #1,FIB$W_FID(R0) ; File ID = (1,1,0), movw #1,FIB$W_FID+2(R0) ; pour INDEXF.SYSB $qiow_s chan=Canal,func=#IO$_ACCESS!IO$M_ACCESS,iosb=Iosb,p1=Fibd blbs R0,3$ brw Erreur3$: blbs Iosb,4$ movzwl Iosb,R0 brw Erreur;4$: clrb Trouve-; Recuperation du nom du fichier a retrouver. pushal LongNam pushaq LongNam pushaq Symbol calls #3,G^Lib$Get_Symbol blbc R0,5$ tstl LongNam bneq 6$; Exit si ^Z ou 5$: $exit_s; Complete avec des blancs&6$: movc5 #20,File,#^A' ',LongNam,File;Read_Home_Block: movab BlocLu,R114 movl #2,NumHead ; Lecture du bloc 2 --> Home Block bsbw read_header0 cmpb HM2$B_STRUCLEV(R11),#2 ; Structure ODS-2 ? beql 1$ ; Oui) movl #SS$_FileSTRUCT,R0 ; Si non, Erreur brw Erreur)1$: movzwl hm2$w_cluster(r11),ClusterSizeB movw HM2$W_IBMAPVBN(R11),NumBitmap ; VBN du 1er bloc de la bitmap8 movw HM2$W_IBMAPSIZE(R11),MapSize ; Taille de la bitmap addl3 NumBitmap,MapSize,Header1$ decl Header1 ; VBN du 1er header2 movw #1,FirstFid ; File Id du 1er header libre 7; Mapping de la bitmap des headers en memoire virtuelle(; Mapping du fichier en section privee) $crmpsc_s inadr=Inadr, retadr=FmapAdr, -" flags=#SEC$M_EXPREG!SEC$M_WRT,-* chan=Canal,vbn=NumBitmap,pagcnt=MapSize blbs r0,2$ brw Erreur@2$: mull2 #512*8,MapSize ; Nb de bits dans la bitmap des headers mnegl #1,FreeHead;Recherche_header_libre: incl FreeHead@2$: cmpl FreeHead,MapSize ; Si on a depasse la taille de bitmap, bleq 1$ ; c'est fini brw fini1$: movl FmapAdr,r0= ffc FreeHead,#32,(r0),FreeHead ; recherche d'un header libre beql 2$ ; Rien Trouve ...;/; On a Trouve le numero d'un header non utilise ; Lisons le/ addl3 FirstFid,FreeHead,FileId ; Calcul du FID> addl3 FileId,Header1,NumHead ; Calcul du VBN dans INDEXF.SYS bsbw Read_HeaderO; Si Iosb n'est pas correct, c'est qu'on a depasse le nombre de blocs alloues.H; ( il n'est pas certain que ce soit possible, mais ca ne coute rien de; verifier...) blbs Iosb,3$ brw Fini;$3$: movzbl FH2$B_IDOFFSET(R11),R10 9 movaw (R11)[R10],R10 ; R10 pointe sur le nom du fichier@; On verifie que tous les caracteres du champ "nom du fichier" J; sont imprimables. Sinon,ce header n'a jamais ete utilise, et on a Fini.Verification_Nom: movl #19,R01$: cmpb (R10)[R0],#^A' ' bgeq 2$2 brw Fini ; Au premier non imprimable,c'est Fini2$: sobgeq R0,1$;9 cmpc3 LongNam,File,(R10) ; S'agit-il du fichier cherche? beql Header_Trouve2 brw Recherche_Header_Libre ; Sinon, on continue;Header_Trouve:E; Etudions ce header, et eventuellement les headers d'extension qui; lui sont chaines... movl NumHead,NumSave;C; Avant de reparer ce header, on va voir dans la bitmap du disqueD; si,par hasard, certains des blocs n'ont pas ete realloues par unH; autre fichier. Si oui, on va simplement abandonner tout espoir de ; recuperation. pushl R11 moval Verif_Bitmap,r9 bsbw Etude_Bitmap popl R110 tstb Ok ; Y-a-t-il au moins 1 bloc realloue ? beql 1$ ; non !; 2$: ; Partiellement realloue7 pushaq undoc_trad ; Le symbole UNDEL$MULTALLOC est-il pushaq undoc_symbol ; connu ?1 calls #2,g^lib$get_symbol ; Si non, on abandonne blbc r0,10$7 pushaq undoc_message ; Si oui, on recupere quand meme, calls #1,g^lib$put_output ; a dieu vat... brb 1$;/10$: pushaq Reallocated ; non recuperable .... calls #1,g^Lib$Put_Output2 brw Recherche_Header_Libre ; passons au suivant;1$:B movzwl FH2$W_EXT_FID(R11),R0 ; FID eventuel du header d'extension; beql Corrige_Header ; y'a pas ou plus d'extensions.: addl3 R0,Header1,NumHead ; Calcul du VBN dans INDEXF.SYS bsbw Read_Header& cmpc3 LongNam,File,(R10) ; meme nom ? bneq 2$ brw Header_Trouve;Corrige_Header:'; Relecture du 1er header si necessaire cmpl NumHead,NumSave beql Recons_Header movl NumSave,NumHead bsbw Read_HeaderRecons_Header:4; On sait maintenant que le fichier est recuperable.?; Dans un premier temps,on va reconstruire la bitmap du disque,,; en marquant alloues les clusters concernes pushl R11 moval Recons_Bitmap,r9 bsbw Etude_Bitmap popl R11;#; Il reste a reconstruire le header;< movw FileId,FH2$W_FID(R11) ; On remet le FID a sa placeB bicl2 #FH2$M_MARKDEL,FH2$L_FILECHAR(R11) ; Suppression du bit qui ; marque le fichier efface$ movl #254,R0 ; Calcul de checksum clrl R11$: addw BlocLu[R0],R1 sobgeq R0,1$= movw R1,FH2$W_CHECKSUM(R11) ; Et positionnement du checksum;; On reecrit le headerF $qiow_s chan=Canal,func=#IO$_WRITEVBLK,p1=BlocLu,p2=#512,p3=NumHead,- iosb=Iosb;-; On marque ce header utilise dans la bitmap movl FmapAdr,R0 addl3 HeadeR1,FirstFid,R1 subl3 R1,NumHead,R1 bbss R1,(R0),2$2$:A; Et on va reconstruire de meme les eventuels headers d'extensionB movzwl FH2$W_EXT_FID(R11),R0 ; FID eventuel du header d'extension4 beql Recupere ; y'a pas ou plus d'extensions.< addl3 R0,HeadeR1,NumHead ; Calcul du VBN dans INDEXF.SYS bsbw Read_Header brw Recons_Header; Recupere:; un Message sur le terminal incb trouve movc3 #20,(R10),Message pushaq MessageDescr calls #1,G^Lib$Put_Output;H brw Recherche_Header_Libre ; Retournons chercher d'autres fichiersFini: movl #SS$_NOSUCHFile,R0 tstb Trouve beql Erreur movl #SS$_NORMAL,R0Erreur: movl R0,Status bsbw Unlock_Volume $dassgn_s chan=Canal $exit_s Status; Verif_Bitmap:E; A l'entree de ce sous-programme, R2 contient le nb de blocs alloues; et R3 le LBN du premier bloc pushl R11 movl BmapAdr,R112 addl2 #512,R11 ; La bitmap demarre au second bloc& divl2 ClusterSize,R2 ; nb de clusters. divl2 ClusterSize,R3 ; Logical Cluster Number1$: bbs R3,(R11),2$ movb #1,Ok 2$: incl R3 sobgeq R2,1$ popl R11 rsb;Recons_Bitmap:E; A l'entree de ce sous-programme, R2 contient le nb de blocs alloues; et R3 le LBN du premier bloc pushl R11 movl BmapAdr,R112 addl2 #512,R11 ; La bitmap demarre au second bloc& divl2 ClusterSize,R2 ; nb de clusters. divl2 ClusterSize,R3 ; Logical Cluster Number1$: bbsc R3,(R11),2$ 2$: incl R3 sobgeq R2,1$ popl R11 rsb; Etude_Bitmap: movzbl FH2$B_MPOFFSET(R11),R0 addl2 R0,R0 9 movzbl FH2$B_MAP_INUSE(R11),R1 ; Nb de Words de map ptrs bneq 1$ ; si 0, fichier vide rsb+1$: addl2 R1,R1 ; nb de bytes de map ptrs/ addl2 R0,R11 ; R11 pointe sur le 1er Map Ptr" clrb Ok ; a priori, tout est bonEtude_Map_pointer:7 extzv #FM2$V_FORMAT,#FM2$S_FORMAT,FM2$W_WORD0(R11),R0  caseb R0,#0,#3$1$: .word 2$-1$ ; Placement control .word 3$-1$ ; Format 1 .word 4$-1$ ; Format 2 .word 5$-1$ ; Format 3#2$: ; Placement Control (ignore) subl2 #FM2$C_LENGTH0,R1 addl2 #FM2$C_LENGTH0,R11 brb Pointer_Suivant3$: ; Format 1$ movzbl FM2$B_COUNT1(R11),R2 ; Count8 extzv #FM2$V_HIGHLBN,#FM2$S_HIGHLBN,FM2$W_WORD0(R11),R3 ashl #16,R3,R3 movw FM2$W_LOWLBN(R11),R3 ; LBN subl2 #FM2$C_LENGTH1,R1 addl2 #FM2$C_LENGTH1,R11 jsb (R9) brb Pointer_Suivant4$: ; Format 2D extzv #FM2$V_COUNT2,#FM2$S_COUNT2,FM2$W_WORD0(R11),R2 ; Block count movl FM2$L_LBN2(R11),R3 ; LBN jsb (R9) subl2 #FM2$C_LENGTH2,R1 addl2 #FM2$C_LENGTH2,R11 brb Pointer_Suivant5$: ; Format 36 EXTZV #FM2$V_COUNT2,#FM2$S_COUNT2,FM2$W_WORD0(R11),R2 ashl #16,R2,R2* movw FM2$W_LOWCOUNT(R11),R2 ; Block count movl FM2$L_LBN3(R11),R3 ; LBN jsb (R9) subl2 #FM2$C_LENGTH3,R1 addl2 #FM2$C_LENGTH3,R11Pointer_Suivant: tstl R1 beql 1$ brw Etude_Map_Pointer1$: rsb; Read_Header:E $qiow_s chan=Canal,func=#IO$_READVBLK,p1=BlocLu,p2=#512,p3=NumHead,- iosb=Iosb rsb; Lock_Volume:" movw #FIB$C_LOCK_VOL,Fib_CtrlFunc: $qiow_s chan=Canal,func=#IO$_ACPCONTROL,iosb=Iosb,p1=Fibd rsb;Unlock_Volume:" movw #FIB$C_UNLK_VOL,Fib_CtrlFunc: $qiow_s chan=Canal,func=#IO$_ACPCONTROL,iosb=Iosb,p1=Fibd rsb; .end Undel