Pale
Member in Training
Posts: 25
|
Post by Pale on Mar 19, 2024 16:13:55 GMT
I have reverse engineered the file structure of a honeywell TDC3000 .lcn file. This is basically a virtual image of the disc system that is used on the Honeywell TDC3000 DCS control system. I use these every day at work. The official method to get the files from the honeywell world to the PC world involves bouncing the data through severil computers and networks and takes for ever . The .lcn file is already in the PC world so I worked out its structure and ASCIIish format and wrote a justbasic program to cut the data files out and convert them to proper ascii. I open a new file and send the ascii to it. This all works great , but the time stamp is now the time that I created the new ascii text file not the date of the original. I have the original date as seconds counted from 2 jan 1979 and I would like to create the new ascci file with the original date to help with keeping track of updates. As the files are often changing and being re-stripped, doing this one at a time is not practical.
Is there any way to set the time/date stamp when creating a file, or after.
Thanks
Pale
|
|
|
Post by Rod on Mar 19, 2024 16:57:23 GMT
Seems to require an API call which puts you in Liberty BASIC territory.
|
|
|
Post by tsh73 on Mar 19, 2024 18:22:50 GMT
Staying with jb, you could use Some command line utility. Like, touch.exe from unxutils.sourceforge.net/
just tried it touch --help shows the options And I did changed creation date, OK
|
|
|
Post by Rod on Mar 20, 2024 10:18:14 GMT
OR, you could incorporate the yyyymmddhhmmss date and time stamp in the file name tdc3000yyymmmddhhmmss.lcn That way you can store files easily knowing the creation date. No API, works in Just BASIC.
|
|
|
Post by xxgeek on Mar 20, 2024 14:06:40 GMT
There is another way using CMD with Powershell. This works here, but I may have different settings in windows, and it may not work for you. It is an example to edit\change to your needs Worth a try?
'change file creation date 'by xxgeek Mar 20 2024 nomainwin global path$, q$, newDate$ path$="pathToFile" 'file to change creation Date eg: "c:\testing\myTestfile.txt newDate$ = "10/21/2015 05:00 pm" 'change the date, but use the same format q$=chr$(34) call writePs1 'cmd runs powershell - changes local policy temporarily and hides the black command window run "cmd.exe /c powershell Set-ExecutionPolicy -ExecutionPolicy UnRestricted -Scope CurrentUser & powershell .\change.ps1",hide end
'write the change.ps1 file sub writePs1 open DefaultDir$;"\change.ps1" for output as #change #change "$(Get-Item ";q$;path$;q$;").creationtime=$(Get-Date ";q$;newDate$;q$;")" close #change end sub
|
|
Pale
Member in Training
Posts: 25
|
Post by Pale on Mar 20, 2024 18:33:40 GMT
Thanks for all your replies . I have started to play with xxgeek's method with power shell. I have it sort of working ( a few issues with directory names with spaces and dashes next to each other? yes it is in quotes. I cant post at the moment as I am at home without the code). Each .lcn file has hundreds of files in it ranging from 20 years old to brand new. Each has its own date. The date is in a 6 byte number counting in seconds. I have pretty much worked out how much offset to take from this and how much to multiply by to get the correct number to put into $(get-date nnnnnnn) in powershell to get the right date in the pc world. I am wondering how long it will take to run all the files through powershell one at a time. I did manage to fill my screen with powershell windows when i clicked on "convert all the files" rather than just "do one" and had to revert to taskmanager to kill justbasic . ( no break key on my laptop). a small delay after the cmd command may stop this. I am intreaged by your run "cmd.exe..... line. Rod it is the time stamp of the files embeded in the .lcn file that is needed and they all vary. @tsh37 alas I am restricted to what I can run on the pc else the IT police at work will jump on me. Once again Thanks all Pale
|
|
|
Post by xxgeek on Mar 20, 2024 18:53:36 GMT
If this is a company computer you are working on you may be in trouble.
Do your "IT police" know you are playing with ExecutionPolicy?
To change multiple files, add them to an array, then loop through the array. That should be quick.
|
|
|
Post by xxgeek on Mar 20, 2024 20:47:11 GMT
Here is some updated code to reset the ExecutionPolicy when it completes.
Also, you may need a slight delay after a RUN line so that CMD gets the file date updated before program starts to flow again. When using a RUN command in your code, the program flow does NOT stop and wait for the results of the RUN command, so you need to program a delay before the next instruction so that, in your case" CMD.exe has time to complete before program executes a command that may use the results from CMD.
Here on my PC a delay of 1/2 second works = 500 miliseconds (approx) But I am not needing it with the code below because I'm not doing anything with the results of CMD or PowerShell actions.
Oh, and use a ,hide like in my code, and you won't have a bunch of powershell windows popping up.
I also commented out 'nomainwin so you can close mainwin if it hangs on you. Also, in the JB menu at top of IDE under RUN>Kill Basic Programs can sometimes work to kill a hung app, or one like this where there is no window to close. Make sure you add a 'scan' command to ensure breaking out of a loop if necessary
'change file creation date 'by xxgeek Mar 20 2024 'nomainwin global path$, q$, newDate$, pol$ path$="path TO file" 'file to change creation Date eg: "c:\testing\myTestfile.txt newDate$ = "08/08/2008 08:00 am" 'change the date, but use the same format q$=chr$(34) call writePs1 run "cmd.exe /c powershell Set-ExecutionPolicy -ExecutionPolicy unRestricted -Scope CurrentUser";_ "& powershell .\change.ps1 & powershell Set-ExecutionPolicy -ExecutionPolicy unDefined -Scope CurrentUser",hide end
sub writePs1 open DefaultDir$;"\change.ps1" for output as #change #change "$(Get-Item ";q$;path$;q$;").creationtime=$(Get-Date ";q$;newDate$;q$;")" close #change end sub
|
|
Pale
Member in Training
Posts: 25
|
Post by Pale on Mar 21, 2024 7:52:16 GMT
Wow loads of info there .
The IT police for some reason in the past made me a local admin. I think someone at the service desk did this to get the encrypted memory stick they insist i use, to work, but kept quiet about it. Not realising that I would notice so I might have un restricted execution anyhow. To be honest this didn't even cross my mind. I had to get permission to use justbasic.
The code I have been using is ( this is just a cut piece)
' data$ holds the equivilent of a FAT and file header . file name date etc 33 to 38 hold the date in seconds from a starting point 'readnumber just converts the bytes into a number
filedate=readnumber(data$,33,6)-4528000900000 'add offset to convert to pc date less=later print readnumber(data$,33,6) 'for debug filedate$=str$(filedate)+"0000" 'convert to string plus add some 00 for powershell print filedate$ 'more debug. pcfile$ is the preselected directory to save to psscript$="$(get-item "+chr$(34)+pcfile$+chr$(34)+").creationtime=$(get-date "+filedate$+")" print psscript$ 'more debug to show what is sent to powershell
run "powershell "+psscript$
Does running a script help at all. I do have an issue with directories.
A psscript$ of
$(get-item "C:\Users\i751579\OneDrive - Archer Daniels Midland Company\Documents\drive-h\basic\my-stuff\lcn\SS.CL").creationtime=$(get-date 634569545411520000)
fails around the " - " bit, when run in basic, but works if pasted into powershell console direct. If i use a directory like "c:\temp" it works in the code ok. The directory is generated by file selector box earlier in the code so the user can select their own choice.
|
|
|
Post by xxgeek on Mar 21, 2024 12:57:33 GMT
A minor oversight Pale
PowerShell wants the date wrapped in quotes too. Should be
psscript$="$(get-item "+chr$(34)+pcfile$+chr$(34)+").creationtime=$(get-date "+chr$(34)+filedate$+chr$(34)+")"
Getting the correct syntax working was a real pain for me too, with same issue of not working in code, but working in powershell console. It seems the console copy/paste is more forgiving than the "programmable" method.
I think when you add the quotes you'll be good to go. crossing fingers xx Let me know what happens.
[Edit] Ok, I tried your date of "634569545411520000" and got an error, it's not in the correct format, so obviously needs to be converted. Your experience with the date$() formats will come in handy.
|
|
Pale
Member in Training
Posts: 25
|
Post by Pale on Mar 21, 2024 18:24:55 GMT
filedate= 62419593600+readnumber(data$,33,4) filedate$=str$(filedate)+"0000000" psscript$="$(get-item "+chr$(34)+pcfile$+chr$(34)+").creationtime=$(get-date "+filedate$+")" run "powershell "+psscript$,minimize psscript$="$(get-item "+chr$(34)+pcfile$+chr$(34)+").lastwritetime=$(get-date "+filedate$+")" run "powershell "+psscript$,minimize
After a bit more reverse engineering I was reading the date in the .lcn file a bit wrong. 4 bytes not 6 . and starts at 1-1-1979. 62419593600 is how many seconds from 1-1-0001 alowing for julian-gregorian. Then add the number I read and add "0000000" on the end ( the same as * 10000000 ) . I tried many variations at work and was pulling my hair out as it would give the wrong date many times. So i bought the files home and had a play here.
filedate= 62419593600+readnumber(data$,33,4)
works but
filedate= readnumber(data$,33,4) +62420932800 - julian correction number + another hour correction number
would not ( i cant recall the julian and hour numbers) in my testing I set the filedate number to 62419593600 and got a timestamp of 1-1-1979. I then added teh read value and it worked. I cant see why the order woud matter.
The powershell windows only stay open for a few seconds when doing many files so that is ok.
I just need to sort the directory issue now.
Thnks for your help
Pale
|
|
|
Post by xxgeek on Mar 21, 2024 19:10:59 GMT
Glad you figured it out Pale, I don't work much with date formats and would have been little help.
P.S. In your code
I don't have access to your readnumber(data,3,4) data etc. Could you provide me with the actual number that goes into the RUN line to use in the new creation date.
I have 62419593600 and 0000000 posted above. but I need the other digits between the 2.
Just for my own curiosity, so I can do some testing and play with it. I need an example Any other relevant info that may help with date formats would also be appreciated.
Thanks Pale. Have a great day.
|
|
|
Post by Rod on Mar 21, 2024 20:39:18 GMT
If the path fails at “ - “ it is very likely Windows taking the “ “ , space character as a separator. The usual solution is to wrap the path in “, or chr$(34) I see you do that already in your string build but perhaps double up the “ when concactinating the path.
|
|
|
Post by xxgeek on Mar 22, 2024 13:30:19 GMT
After a few experiments I found some more formats that work for the Date.
'newDate$ = "September 14 2002 09:00 pm" ' -works Month Day Year hour:minute pm or am 'newDate$ = "15 May 2007 08:00 am" ' - works Day Month Year hour:minute am or pm 'newDate$ = "4/10/2015 2:00 am" ' - works Month/Day/Year hour:minute am or pm 'newDate$ = "01/21/2015 05:00 pm" '- works using 01 or just 1 and 05 or just 5 'newDate$ = "2-11-2005 7:00 am" ' - works Month/Day/Year hour:minute am or pm 'newDate$ = "2-May-2005 7:00 am" ' - works Day/Month/Year hour:minute am or pm 'newDate$ = "September-14-2002 09:00 pm" ' -works Month Day Year hour:minute pm or am newDate$ = "August 14 2002 09:00 pm" ' -works Month Day Year hour:minute pm or am
Also, I experimented with the syntax of the RUN line and found that what I posted originally is what works. I found no other syntax that will work for me.
Both the newDate$, and the Path$ need to be wrapped in quotes.
AND, it seems to work ONLY when run from a script as in my original post. When RUN from JB code, it gives an error.
I would like a copy of the long number Pale is using for filedate$. The number that is the result of : filedate= 62419593600+readnumber(data$,33,4) filedate$=str$(filedate)+"0000000"
A copy of one of the problem path$ might help with figuring out this issue too.
|
|
Pale
Member in Training
Posts: 25
|
Post by Pale on Mar 23, 2024 17:03:42 GMT
I am not at work at the moment but here is an example I just made with my out of date code copy. A typical number you are missing would be 1268486320 . in this example Data$ holds 4 bytes at positions 33,34,35,36 these have the values in hex of h4B h9B h90 hB0 . So readnumber(data$,33,4) returns 1268486320 . This should be 1268486320 seconds past 1-1-1979 00:00:00 = 13-03-2019 13:18:00 give or take a few seconds '************************************************* ' read byte, word, longword etc. from data in the form of a string ' read bytes from string and turn multibyte number into integer ' chr$(10),chr$(10)= 10 *256+10 = 2570. function readnumber(data$,address,bytes)
number = 0 for n = 0 to bytes-1 number = number*256 + asc(mid$(data$,address+n,1)) next n readnumber = number
end function
'**************************************************
There have been two errors My first error as mentioned above was reading 6 bytes not 4. When looking at the raw data I noticed that the last two bytes were always h8000 . I also compared the dates of two files edited at the similar times and worked out that I needed just the top 4 bytes. The second issue that I noticed yesterday is that the honeywell time stamp did not match the time written in the code source I am ripping. The example above dated 13-3-2019 was modded on 30-3-17 acording to the comments in the code. Thus throwing me a curve ball! Some one not following the correct update procedure. The following works for the date part ' 01-01-1979 00:00:00 = 62419593600 seconds
filedate= 62419593600+readnumber(data$,33,4) filedate$=str$(filedate)+"0000000" psscript$="$(get-item "+chr$(34)+pcfile$+chr$(34)+").creationtime=$(get-date "+filedate$+")" run "powershell "+psscript$,minimize psscript$="$(get-item "+chr$(34)+pcfile$+chr$(34)+").lastwritetime=$(get-date "+filedate$+")" run "powershell "+psscript$,minimize
the string $(get-item "C:\temp\i234567\onedrive - archer dan mid\E_AUX.CL").creationtime=$(get-date 636880799200000000) fails when sent to powershell via the RUN command but works if you paste direct into powershell When running multiple saves at work the screen stalled long enough for me to momentarily see an error that marked the - . the string (note the extra quotes) $(get-item ""C:\temp\i234567\onedrive - archer dan mid\E_AUX.CL"").lastwritetime=$(get-date 636880799200000000) works from the run command but not when pasted direct. The run command must strip the quotes. SO extra quotes for the run command (Thanks Rod) psscript$="$(get-item "+chr$(34)+chr$(34)+pcfile$+chr$(34)+chr$(34)+").lastwritetime=$(get-date "+filedate$+")"
I hope that all makes sense
Thanks Pale
|
|