/* Pump Up the Volume ! Auteur : Arnaud C. (pour WWW.CTRL-POMME-RESET.FR) v0.71 - 05.06.2013 convertit des DSK vers des fichiers NIB (utilisation de dsk2nib.jar) en intégrant le bon numéro de volume, reconnu grâce un fichier de base de données. dsk2nib.jar (c) Jean-Marc Boutillon / modifications légères : CPR (http://boutillon.free.fr/Underground/Outils/dsk2nib/dsk2nib.html) Historique : ============ - 0.71 : molette souris reconnue pour le défilement des infos dans la fenêtre principale. - 0.70(*) : modification interface générale (ajout de boutons). - 0.61 : ajout du drag-n-drop vers la fenêtre principale. - 0.60 : ajout des modificateurs de comparaison !XX (différent de XX) et * (ignorer). - 0.56(*) : ajout de guillemets au nom de fichiers pour éviter des erreurs avec dsk2nib.jar (si espaces). - 0.55(*) : ajout boite de dialogue pour entrer le volume manuellement en cas de non reconnaissance auto. - 0.53(*) : améliorations mineures/corrections bugs. - 0.5 (*) : amélioration du format du fichier externe "volume" + corrections de bugs. - 0.4 (*) : ajout GUI pour l'affichage des informations. - 0.3 (*) : premier jet pour la prise en compte d'un fichier externe "volume". - 0.2 (*) : ajout support multi-fichiers. - 0.1 (*) : première version (fichier simple). (*) : version de travail, non released */ #NoEnv #SingleInstance force #MaxHotkeysPerInterval 200 ;================================================================== title = Pump Up the Volume ! v0.71 ;================================================================== ParamFile = PUV-List.txt ; nom du fichier de paramètres ;ParamFile = PUV-test.txt ; nom du fichier de paramètres (test only) JarName = dsk2nib.jar ; nom utilisé pour disk2nib.jar ;================================================================== Gui, Font, s8, Lucida Console Gui, Add, Edit, cWhite W400 H300 ReadOnly hwndhInfoZone vInfoZone Gui, Color,Black, Black Gui, Add, Button, X10 Y310 W200 gOpenF, &Open .dsk Files Gui, Add, Button, X210 Y310 W200 gReload, &Reload Database Gui, Show, AutoSize Center, %title% GroupAdd, PUMP, %title% ; on ajoute la fenêtre au groupe PUMP (utilisé pour les hotkeys) ; ================================================================= main: ifNotExist, %JarName% { GuiControl,, InfoZone, ERROR : disk2nib.jar not found ! return } else { TextInfoZone = disk2nib.jar ok. `n`n GuiControl,, InfoZone, %TextInfoZone% } ReadDatabase() ; ouverture + lecture fichier de config/database return ; ================================================================= ReadDatabase() ; ouverture + lecteur fichier database { global ;global ContentFile, ParamFile, TextInfoZone ; partie 0 : récupération info fichier config : fonctionnement contentFile Ligne_Groupe FileRead, InitFile,%ParamFile% ; ouverture fichier de Volume if ErrorLevel ; check si ouverture/lecture OK { GuiControl,, InfoZone, ERROR : Volume Database File couldn't be opened ! return } TextInfoZone = %TextInfoZone%Volume Database File loaded.`n`n GuiControl,, InfoZone, %TextInfoZone% StringSplit, LineArray, InitFile, `n ; on split chaque ligne du fichier texte ind = 1 ; initialisation à 1 pour l'index de ligne Loop, %LineArray0% { StringSplit, var,LineArray%a_index%, `,%A_Tab%,%A_Space% ; on récupère le contenu de chaque élément d'une ligne dans var (séparateurs reconnus , et TAB) StringLeft, temp, var1, 1 ; on récupère le premier caractère de chaque ligne if (temp = "/" | temp = "*" | temp = ";" | temp = "`n") ; on shunte les lignes de commentaires / lignes vide ! { continue ; on passe à la ligne suivante } if (var0 <3) ; si ligne de donnée non complète, on shunte aussi { continue ; on passe à la ligne suivante } ind2 = 1 ; on initialise à 1 pour l'index param du contenu de ligne Loop, %var0% ; on place le contenu de chaque ligne dans le double tableau contentFile ligne_variable { StringReplace,temp, var%a_index%,%A_Tab%,,all ; on supprime tous les TAB éventuels if (temp = "") ; si contenu = chaine vide, on passe à la suite { continue } ContentFile%ind%_%ind2% := temp ; contentFile ligne_variable ind2++ } ind++ ; on augmente l'index de ligne (=lignes valides du fichier param) } nbCheck := ind-1 ; on récupère le nombre de vérif à effectuer (une par ligne valide) } ; ================================================================= ParsingDSK(filenames, bDrop) ; parsing DSK files ; filenames contient la chaine avec la liste des files ; bDrop boléen à 0 si ouverture par FileSelectFile ou à 1 si ouverture par Drag'n'Drop { global JarName, TextInfoZone, hInfoZone nb = 0 ; initialisation nombre de fichiers traités correctement it = 0 ; initialisation itération boucle if (bDrop = 0) ; ouverture normal fichiers .DSK (par boite de dialogue de sélection) { Loop, parse, filenames, `n ; on parse les fichiers sélectionnés { if (a_index = 1) { path = %A_LoopField% ; le premier élément est le nom du rep, on le récup FileCopy, %JarName%, %A_LoopField%\dskxxxnib.jar, 1 ; copie de disk2nib vers le répertoire SetWorkingDir, %path% ; on fixe le répertoire de travail } else { file = %A_LoopField% ; fichier (sans path !) ret := traitement(file,path) ; on traite les éléments suivants if (ret=0) nb++ ; compteur de fichier réellement traités } it++ ; compteur de boucle pour savoir le nb de fichiers qui étaient à traiter } } else ; fichiers .DSK drag and droped ! { bDrop = 0 ; on remet à zéro pour éviter de rester en mode drag and drop Loop, parse, filenames, `n ; on parse les fichiers sélectionnés { if (a_index = 1) ; premier fichier avec lequel on récupère aussi le path { SplitPath, A_LoopField,,path ; on récupère le directory du fichier FileCopy, %JarName%, %path%\dskxxxnib.jar, 1 ; copie de disk2nib vers le répertoire SetWorkingDir, %path% ; on fixe le répertoire de travail file = %A_LoopField% ; fichier + chemin complet SplitPath, file, file2 ; on ne garde que le nom de fichier ret := traitement(file2,path) ; on traite le premier fichier if (ret=0) nb++ ; compteur de fichiers réellement traités it++ ; on ré-équilibre le nombre de file traité (+ 1 ici car le premier est également traité) // bidouille ! } else { file = %A_LoopField% ; fichier + chemin complet SplitPath, file, file2 ; on ne garde que le nom de fichier ret := traitement(file2,path) ; on traite les éléments suivants if (ret=0) nb++ ; compteur de fichiers réellement traités } it++ ; compteur de boucle pour savoir le nb de fichiers qui étaient à traiter } } if (nb = it-1) { TextInfoZone = %TextInfoZone%`nALL files (%nb%) volumed !`n`n`n`n GuiControl,, InfoZone, %TextInfoZone% } else { temp := it-nb-1 TextInfoZone = %TextInfoZone%`n%nb% files volumed and ERROR with %temp% file(s)`n`n`n`n GuiControl,, InfoZone, %TextInfoZone% } SendMessage, 0x0115, 7, 0,, ahk_id %hInfoZone% ; WM_VSCROLL ! (scroll to bottom) FileDelete, dskxxxnib.jar ; on supprime le jar une fois utilisé ! FileDelete, logpuv.tmp ; on supprime le logpuv.tmp return } ; ================================================================= ; partie II : traitement du fichier DSK traitement(file,path) ; fonction traitement { global nbCheck, ContentFile, TextInfoZone TextInfoZone = %TextInfoZone%%file% :`n GuiControl,, InfoZone, %TextInfoZone% FileGetSize, size, %file% ; check file size if (size <> 143360) { TextInfoZone = %TextInfoZone% ERROR : not a valid DSK file (size mismatch)`n`n GuiControl,, InfoZone, %TextInfoZone% return 1 } FileRead, Buffer,%file% ; lecture fichier if ErrorLevel ; check si ouverture/lecture OK { TextInfoZone = %TextInfoZone% ERROR : couldn't be opened`n`n GuiControl,, InfoZone, %TextInfoZone% return 1 } ; partie II/A : on check à l'offset pour voir si on a bien les data attendues et ce pour chaque ligne de param correspondanceOK = 0 ; on initialise à zero Loop, %nbCheck% ; boucle 1 : pour chaque ligne de param { ; on récupère la valeur de l'offset : numberLine := a_index temp := ContentFile%a_index%_1 ; offset temp2 = 0x%temp% ; mise en forme hexa offset := temp2 ; on récupère les data à comparer : data := ContentFile%a_index%_2 ; data nbOK = 0 ; nb de bytes traités OK (si = 0, au moins un byte ne correspond pas) indData = 1 ; index data chaine = premier caractère de la chaine data indDataLoaded = 1 ; index data loaded (du fichier) Loop ; boucle 2 : BYTE à checker { StringMid, temp, data,indData, 1 ; on récupère le premier caractère du groupe de byte dataloaded := NumGet(Buffer, offset-1+indDataLoaded,"UChar") ; on récupère le byte hexa issu du fichier DSK if (temp = "") ; si on est arrivé au bout de la chaine { break ; on sort de la boucle "BYTE à checker" } else if (temp = "*") ; * => on shunte et on passe au byte suivant { nbOK++ ; on augmente le nb de byte OK indData++ ; on passe au BYTE immédiat après le * dans la chaine indDataLoaded ++ ; on passe au BYTE hexa suivant du fichier DSK } else if (temp = "!") ; * => on vérifie que le byte suivant n'EST PAS égal { indData++ 3 ; on positionne l'index de la chaine sur le caractère suivant StringMid, temp, data, indData, 2 ; on récupère les deux car. suivants (= 1 BYTE Hexa) temp2 = 0x%temp% ; mise en forme hexa if (temp2 = dataloaded) ; s'il y a correspondance (ce qu'on ne veut pas ici) { nbOK = 0 ; on remet à zéro (bad chaine) break ; on sort de la boucle "BYTE à checker" } else ; s'il n' y a pas de correspondance (donc OK ici) { nbOK++ ; sinon , on augmente le nb de byte OK indData := indData +2 ; on se positionne sur le prochaine BYTE dans la chaine indDataLoaded++ ; on se positionne sur le prochain byte hexa dans le DSK } } else ; comparaison normale (correspondance) { StringMid, temp, data, indData, 2 ; on récupère les deux car. (= 1 BYTE Hexa) temp2 = 0x%temp% ; mise en forme hexa if (temp2 <> dataloaded) ; s'il n'y a pas correspondance { nbOK = 0 ; on remet à zéro (bad chaine) break ; on sort de la boucle "BYTE à checker" } else ; s'il y a correspondance (donc OK) { nbOK++ ; sinon , on augmente le nb de byte OK indData := indData +2 ; on se positionne sur le prochaine BYTE dans la chaine indDataLoaded++ ; on se positionne sur le prochain byte hexa dans le DSK } } } if (nbOK <> 0) ; si le nb de byte OK est différent de zéro alors la comparaison est OK { correspondanceOK = 1 ; info := ContentFile%numberLine%_4 ; on récupère le "commentaire" TextInfoZone = %TextInfoZone% volume matched with : %info%`n ; et on l'affiche GuiControl,, InfoZone, %TextInfoZone% break ; on sort de la boucle "ligne" } } if (correspondanceOK = 0) ; aucune correspondance trouvée { TextInfoZone = %TextInfoZone% No match found ! Enter Volume Manually `n`n GuiControl,, InfoZone, %TextInfoZone% InputBox, infoVolume, Enter Volume (in hexa) for :, %file% ,,300,120,,,,20 if (ErrorLevel = 1 or ErrorLevel = 2) { return 1 ; sortir si CANCEL ou TIMEOUT } temp2 = 0x%infoVolume% ; mise en forme HEXA volume :=temp2 } else { infoVolume := ContentFile%numberLine%_3 ; info volume StringLeft, check, infoVolume, 1 ; on récupère le premier car de l'info volume if (check = "&") ; si info volume = offset { StringTrimLeft, temp, infoVolume, 1 ; on virre le premier caractère (&) pour obtenir l'offset du Volume temp2 = 0x%temp% ; mise en forme hexa offVolume := temp2 ;volume := *(&Buffer+offVolume) ; on récupère le numéro de volume volume := NumGet(Buffer,offVolume,"UChar") } else ; si info volume = directement le numéro du volume { temp2 = 0x%infoVolume% ; conversion à l'arrache vers l'hexa en rajoutant 0x volume :=temp2 } } if (volume > 255 or volume < 0) { TextInfoZone = %TextInfoZone% ERROR : bad volume number (%volume%) !`n`n GuiControl,, InfoZone, %TextInfoZone% return 1 } SetFormat, IntegerFast, D ; on met en décimal pour transmettre à dsk2nib.jar volume +=0 ; opération neutre pour forcer la convertion vers décimal TextInfoZone = %TextInfoZone% volume number : %volume% `n launching dsk2nib :`n GuiControl,, InfoZone, %TextInfoZone% file2 = "%file%" ; ajout guillemets pour éviter les problèmes d'espace(s) notamment, avec dsk2nib RunWait %comspec% /c java -jar dskxxxnib.jar %volume% %file2% 1>logpuv.tmp 2>&1,, Hide ret = %ERRORLEVEL% ; on récupère le retour du JAR (0 = OK / 1 = ERROR) FileRead, log,logpuv.tmp TextInfoZone = %TextInfoZone%%log% `n`n GuiControl,, InfoZone, %TextInfoZone% return %ret% ; on retourne (0 = OK/ 1 = ERROR) } ; ================================================================= GuiClose: ; si on ferme la GUI, on quitte le script ! ExitApp ; ================================================================= GuiDropFiles: SetWorkingDir %A_ScriptDir% ; on remet le répertoire de travail par défaut ! filenames := A_GuiEvent ; si files dropped, on met la liste dans filenames ParsingDSK(filenames, 1) ; parsing DSK avec Drag'n'Drop ON ! return ; ================================================================== OpenF: ; si ouverture files par boite de dialog (bouton : "open .dsk files") FileSelectFile, filenames,M3,,Select DSK file,DSK Files (*.dsk) if filenames = return ; the user press cancel SetWorkingDir %A_ScriptDir% ; on remet le répertoire de travail par défaut ! (car si drag and drop depuis la BdD) ParsingDSK(filenames, 0) ; parsing DSK avec Drag'n'Drop OFF return Reload: TextInfoZone := "" SetWorkingDir %A_ScriptDir% ; on remet le répertoire de travail par défaut ! ReadDatabase() return ; =================================================================== #IfWinActive, ahk_group PUMP ^r::Reload ; CTRL+R => reload le script (et le relance) return #IfWinActive, ahk_group PUMP WheelDown:: SendMessage, 0x0115, 1, 0,, ahk_id %hInfoZone% ; WM_VSCROLL ! (SB_LINEDOWN) return #IfWinActive, ahk_group PUMP WheelUp:: SendMessage, 0x0115, 0, 0,, ahk_id %hInfoZone% ; WM_VSCROLL ! (SB_LINEUP) return