Programatically Change Attributes of Windows File with Wild Cards (*.jpg) in VFP - attributes

Hoping to use a windows shell API call that can accept wild cards to change attributes programmatically. Utmost thanks/blessings for any/all thoughts.
Borrowing code from http://www.resolvinghere.com/sm/how-do-i-change-an-attribute-of-a-file-from-within-a-visual-foxpro-program.shtml
RUN /N ATTRIB +H "c:\test.txt" && Hidden causes dos window to noise itself
RUN /N ATTRIB -H "c:\test.txt" && UnHidden
Tom recalled this ... but it does not take wild-cards:
*------------CHAR-------HEX------------------BIN---------NUM
* READONLY R 0x00000001 00000000 00000001 1
* HIDDEN H 0x00000002 00000000 00000010 2
* SYSTEM S 0x00000004 00000000 00000100 4
* DIRECTORY D 0x00000010 00000000 00010000 16
* ARCHIVE A 0x00000020 00000000 00100000 32
* NORMAL N 0x00000080 00000000 10000000 128
* TEMPORARY T 0x00000100 00000001 00000000 256
* COMPRESS C 0x00000800 00001000 00000000 2048
* NOINDEX I 0x00002000 00100000 00000000 8192
* CHIPHER P 0x00004000 01000000 00000000 16384
* ERROR 0xFFFFFFFF REPL("1",32) 4294967295
* ----------------------------------------------------------------------
LPARAMETER vFilename as String, vNewAttribute as String
LOCAL liFlag as Integer, llResult, liAttributes, lnNewAttribute, cDummy, nBitPos, cBitMap
DECLARE INTEGER SetFileAttributes IN Win32API STRING, INTEGER
DECLARE INTEGER GetFileAttributes IN Win32API STRING
llResult = .F.
IF !EMPTY(vFilename)
IF VARTYPE(vNewAttribute) = [C]
lnNewAttribute = 0
* 1234567890123456
cBitMap = [RHS DA NT C IP ]
FOR i = 1 TO LEN(vNewAttribute)
cDummy = SUBSTR(vNewAttribute,i,1)
nBitPos = AT(cDummy,cBitMap)
IF nBitPos > 0
lnNewAttribute = BITSET(lnNewAttribute, nBitPos -1 )
ENDIF
ENDFOR
ELSE
lnNewAttribute = vNewAttribute
ENDIF
liAttributes = GetFileAttributes(vFilename)
IF (liAttributes # -1)
lnNewAttribute = BITXOR(liAttributes, lnNewAttribute)
llResult = (SetFileAttributes(vFilename, lnNewAttribute) = 1 )
ENDIF
ENDIF
RETURN llResult

Of course RUN ... should not be one of your selections to accomplish a procedure where you don't need to shell to DOS at all.
Your question is two fold:
How do get a list of files using a wildcard + in all subdirectories.
For this one you can use a bunch of alternatives such as FileSystemObject, Adir() or Filer.dll that ships with VFP and maybe more. Here I will sample with the Filer.dll (which is also the DLL used in HOME()+'tools\filer\filer.scx' ). Here is one enhanced wildcard match using filer:
*GetTree.prg
Lparameters tcStartDir,tcSkeleton,tcCursorName,;
tlSubfolders,;
tlWholeWords,tlIgnoreCase,tlSearchAnd,tcSearch1,tcSearch2,tcSearch3
Create Cursor (m.tcCursorName) ;
(filepath m, filename m, ;
FileSize i, fattr c(8), createtime T, lastacc T, lastwrite T)
Local oFiler, lnFound
oFiler = Createobject('filer.fileutil')
With m.oFiler
.SearchPath = m.tcStartDir
.FileExpression = m.tcSkeleton && Search for skeleton
.Subfolder = Iif(m.tlSubfolders,1,0) && Check subfolders
.IgnoreCase = Iif(m.tlIgnoreCase,1,0)
.WholeWords = Iif(m.tlWholeWords,1,0)
.SearchAnd = Iif(m.tlSearchAnd,1,0)
.SearchText1 = Iif(Empty(m.tcSearch1),"",m.tcSearch1)
.SearchText2 = Iif(Empty(m.tcSearch2),"",m.tcSearch2)
.SearchText3 = Iif(Empty(m.tcSearch3),"",m.tcSearch3)
lnFound = .Find(0)
For ix=1 To m.lnFound
With .Files(m.ix)
If !(Bittest(.Attr,4) And .Name = '.')
Insert Into (m.tcCursorName) ;
(filepath, filename, FileSize, fattr, createtime, lastacc, lastwrite) ;
values ;
(.Path, .Name, .Size, Attr2Char(.Attr), ;
Num2Time(.Datetime), Num2Time(.LastAccessTime), Num2Time(.LastWriteTime))
Endif
Endwith
Endfor
Endwith
Return m.lnFound
Function Num2Time
Lparameters tnFloat
Return Dtot({^1899/12/30}+Int(m.tnFloat))+86400*(m.tnFloat-Int(m.tnFloat))
Function Attr2Char
Lparameters tnAttr
Return ;
IIF(Bittest(m.tnAttr,0),'RO','RW')+;
IIF(Bittest(m.tnAttr,1),'H','_')+;
IIF(Bittest(m.tnAttr,2),'S','_')+;
IIF(Bittest(m.tnAttr,4),'D','_')+;
IIF(Bittest(m.tnAttr,5),'A','_')+;
IIF(Bittest(m.tnAttr,6),'E','_')+;
IIF(Bittest(m.tnAttr,7),'N','_')
How do I set the attributes.
If you are not after those fancy attributes, that are rarely used, here is the function I have written for myself:
*SetFAttributes.prg
lparameters tcFileName, tlReadOnly, tlHidden, tlSystem
#define FILE_ATTRIBUTE_READONLY 0x00000001
#define FILE_ATTRIBUTE_HIDDEN 0x00000002
#define FILE_ATTRIBUTE_SYSTEM 0x00000004
local lnNewAttr
lnNewAttr = iif(m.tlReadonly,FILE_ATTRIBUTE_READONLY,0)+;
iif(m.tlHidden,FILE_ATTRIBUTE_HIDDEN,0)+;
iif(m.tlSystem,FILE_ATTRIBUTE_SYSTEM,0)
declare integer SetFileAttributes in Win32API ;
string # lpFileName, integer dwFileAttributes
declare integer GetFileAttributes in Win32API ;
string # lpFileName
return ( SetFileAttributes(#tcFilename, ;
bitor(bitand(GetFileAttributes(#tcFilename),0xFFFFFFF8),m.lnNewAttr)) = 1)
Having the above prg files on hand, lets say you want to set all .txt files under c:\MyFolder and its subfolders to readonly, (not hidden, not system) you would be doing this:
Local lcFileName
GetTree('c:\MyFolder','*.txt', 'myCursor', .T.)
Select myCursor
scan for Atc('D',fAttr) = 0
lcFileName = Addbs(Trim(FilePath))+Trim(FileName)
SetFAttributes(m.lcFileName, .T., .F., .F.)
endscan

Related

Wav file corrupted header

Is there any tool that helps with fixing a .wav file header other than Audacity?
The file is playing pure noise on audacity and doesn't open in other applications at all.
I believe the header is corrupted and not sure which value to use for "offset".
Here is a sample file: .wav corrupted file download 4 mgb
Here is another file just to confirm:
Another corrupted .wav file 35 mgb
To get a grip on an unknown binary file its always good advice to pop it open using a hex editor ... https://www.wxhexeditor.org/
The file looks to be a binary dump of some web page ... notice the right column showing HTML
or issue this terminal command to render each byte in boolean and its ASCII counterpart
xxd -b name_of_given_binary_file
00000000: 00111100 00100001 01000100 01001111 01000011 01010100 <!DOCT
00000006: 01011001 01010000 01000101 00100000 01101000 01110100 YPE ht
0000000c: 01101101 01101100 00111110 00001010 00111100 00100001 ml>.<!
00000012: 00101101 00101101 01011011 01101001 01100110 00100000 --[if
00000018: 01101100 01110100 01100101 00100000 01001001 01000101 lte IE
0000001e: 00100000 00111000 01011101 00111110 00111100 01101000 8]><h
00000024: 01110100 01101101 01101100 00100000 01100011 01101100 tml cl
0000002a: 01100001 01110011 01110011 00111101 00100010 01101110 ass="n
00000030: 01100111 00101101 01100011 01110011 01110000 00100000 g-csp
od -a name_of_given_binary_file # octal dump is handy here too
0000000 < ! D O C T Y P E sp h t m l > nl
0000020 < ! - - [ i f sp l t e sp I E sp 8
0000040 ] > < h t m l sp c l a s s = " n
0000060 g - c s p sp i e sp i e 8 sp l t e

How do you interpret a bit string using sharp snmp lib (hrPrinterDetectedErrorState)?

How do you interpret hrPrinterDetectedErrorState (http://cric.grenoble.cnrs.fr/Administrateurs/Outils/MIBS/?oid=1.3.6.1.2.1.25.3.5.1.2) or something like it using Sharp Snmp lib? Is there some kind of bit string type? It's kind of a bitmask, but you may only receive one byte instead of two (or I've seen four bytes).
Did it on my own in powershell.
[flags()] Enum hrPrinterDetectedErrorState
{
lowPaper = 0x8000
noPaper = 0x4000
lowToner = 0x2000
noToner = 0x1000
doorOpen = 0x0800
jammed = 0x0400
Offline = 0x0200
serviceRequested = 0x0100
inputTrayMissing = 0x0080
outputTrayMissing = 0x0040
markerSupplyMissing = 0x0020
outputNearFull = 0x0010
outputFull = 0x0008
inputTrayEmpty = 0x0004
overduePreventMaint = 0x0002
notUsed = 0x0001
}
function snmpmessage($data) {
$bytes = [byte[]][char[]]$data
# pack up to two bytes into an int left to right
$code = [int]$bytes[0]
$code = $code -shl 8
if ($bytes[1]) { $code = $code + $bytes[1] }
[hrPrinterDetectedErrorState]$code
}
PS C:\> snmpmessage -join [char[]](0x91,0x04)
inputTrayEmpty, serviceRequested, noToner, lowPaper

ARM Assembly accepting '-'

So my code currently converts a string into a integer. My code is currently working and functional however, i need it to accept an "-" at the beginning of the input to judge if it is a negative or not. I have no idea how to do this and i can not find any sources. I am currently passing in (test3: .asciz "-48") into register r0. and when i run in the debugger i am receiving 45. here is my code for reference.
.global stoi
.text
stoi:
push {r4,r5,r6,r8,r9,lr}
#r0 = buffer
mov r1,#0 #r1 = n = 0
mov r9,#0 #buffer counter
mov r4,#48 #0 checker
mov r5,#57 #9 checker
b 5f
5:
ldrb r3,[r0,r9] #r3 = c
b 1f
1:
cmp r3,r4 #cmp c to 0(48 in ASCII)
bge 2f
b 4f
2:
cmp r3,r5 #cmp c to 9(57 in ASCII)
ble 3f
b 4f
3:
sub r6,r3,#'0' #r6 = (c - '0')
#strb r6,[r0,r9]
add r1,r1,r1,lsl#2 #r1 = n * 10
add r1,r1,r1,lsl#0
add r1,r1,r6 #n = n * 10 + (c - '0')
add r9,r9,#1 #add to buffer
b 5b
4:
mov r0,r1
pop {r4,r5,r6,r8,r9,pc}
use the same code you're using now, and add these changes:
1) skip the '-' if it's the first char.
Right now you're stopping if a non-digit char is read, you receive 45 (in R3), it is the ascii of '-'. Afais R1 should still be 0 tho
2) At the end, add a check if the first char is a '-', and if it is, subtract r1 from 0 (since 0 - x is -x)
( 3) remove the b 1f, it's not needed ;) )

How to read a C generated binary file in Lua

I want to read a 32 bit integer binary file provided by another program. The file contains only integer and no other characters (like spaces or commas). The C code to read this file is as follows:
FILE* pf = fopen("C:/rktemp/filename.dat", "r");
int sz = width*height;
int* vals = new int[sz];
int elread = fread((char*)vals, sizeof(int), sz, pf);
for( int j = 0; j < height; j++ )
{
for( int k = 0; k < width; k++ )
{
int i = j*width+k;
labels[i] = vals[i];
}
}
delete [] vals;
fclose(pf);
But I don't know how to read this file into array using Lua.
I've tried to read this file using io.read, but part of the array looks like this:
~~~~~~xxxxxxxxyyyyyyyyyyyyyyzzzzzzzz{{{{{{{{{|||||||||}}}}}}}}}}}~~~~~~~~~xxxxxxxyyyyyyyyyyyyyyzzzzzz{{{{{{{{{{|||||||||}}}}}}}}}}}~~~~~~~~~xxyyyyyyyyyyyyyzzzzz{{{{{{|||}}}yyyyyyyyyyyz{{{yyyyyyyyÞľūơǿȵɶʢ˺̤̼ͽаҩӱľǿجٴȵɶʢܷݸ˺໻⼼ӱľǿ
Also the Matlab code to read this file is like this:
row = image_size(1);
colomn = image_size(2);
fid = fopen(data_path,'r');
A = fread(fid, row * colomn, 'uint32')';
A = A + 1;
B = reshape(A,[colomn, row]);
B = B';
fclose(fid);
I've tried a function to convert bytes to integer, my code is like this:
function bytes_to_int(b1, b2, b3, b4)
if not b4 then error("need four bytes to convert to int",2) end
local n = b1 + b2*256 + b3*65536 + b4*16777216
n = (n > 2147483647) and (n - 4294967296) or n
return n
end
local sup_filename = '1.dat'
fid = io.open(sup_filename, "r")
st = bytes_to_int(fid:read("*all"):byte(1,4))
print(st)
fid:close()
But it still not read this file properly.
You are only calling bytes_to_int once. You need to call it for every int you want to read. e.g.
fid = io.open(sup_filename, "rb")
while true do
local bytes = fid:read(4)
if bytes == nil then break end -- EOF
local st = bytes_to_int(bytes:byte(1,4))
print(st)
end
fid:close()
Now you can use the new feature of Lua language by calling string.unpack , which has many conversion options for format string. Following options may be useful:
< sets little endian
> sets big endian
= sets native endian
i[n] a signed int with n bytes (default is native size)
I[n] an unsigned int with n bytes (default is native size)
The arch of your PC is unknown, so I assume the data to read is unsigned and native-endian.
Since you are reading binary data from the file, you should use io.open(sup_filename, "rb").
The following code may be useful:
local fid = io.open(sup_filename, "rb")
local contents = fid:read("a")
local now
while not now or now < #contents do
local n, now = string.unpack("=I4", contents, now)
print(n)
end
fid:close()
see also: Lua 5.4 manual

MCP2200 linux settings

Im want to control MCP2200 in linux.
I found Text Link and set everything.
For example:
I type in console
GP3-1
It will sets pin 3 to 1. But i dont know what to type in console
for controlling the mcp2200 you will need a program doing the stuff for you.
The USBtoUART didn't work for me, maybe you'll have to do some coding yourself - but you can use it to understand how to connect to the mcp2200 hid.
For controlling the IOs, just set up a 16-byte array, filled with the data described here:
http://ww1.microchip.com/downloads/en/DeviceDoc/93066A.pdf
If you want to control some more stuff but gpios, you'll have to do some more - it is possible to control more than just the gpios of the mcp2200 from linux.
I did a little usb trace of the communication of the windows config tool, extracted some informations and - tadaah, there you go with your own pID/vID, Manufacturer and Product strings.
Note: you'll probably need the HIDAPI MikeF was talking about.
First of all, some definitions:
// NOTE: max. string length for manufacturer / product string is 63 bytes!!
// from usb trace of mcp2200 config tool
#define MCP2200_SECRET_CONFIGURE 0x01
#define MCP2200_CFG_PID_VID 0x00
#define MCP2200_CFG_MANU 0x01
#define MCP2200_CFG_PROD 0x02
... and some variables:
unsigned char **mcp2200_manu_string;
unsigned char **mcp2200_prod_string;
The output message for manufacturer string looks like
/* configure manufacturer string (16 x 16 bytes):
* output buffer:
* #0: [01 01 00 16 03 58 00 4B 00 72 00 FF FF FF FF FF]
* | | | | | | | | | | | +-----------+--> Always FF
* | | | | | | +-----+-----+-----------------> Always 00
* | | | | | +-----+-----+--------------------> First 3 Chars of Manufacturer Name / Product Name
* | | | | +-----------------------------------> In #0: 0x03, After #0: 0x00
* | | | +--------------------------------------> (Length (Manufacturer Name) * 2) + 2 (after #0: chars of manufacturer name)
* | | +-----------------------------------------> Counter 0x00 .. 0x0F
* | +--------------------------------------------> MCP2200 Config Bit (MCP2200_CFG_MANU / PROD / VID_PID)
* +-----------------------------------------------> MCP2200_SECRET_CONFIGURE from usb trace
*/
if you put all this in a function, it could look like this:
void prepare_cfg_strings (char* manu, char* prod) {
char manuStr[64];
char prodStr[64];
unsigned int i, k = 0;
unsigned char tmp = 0;
memset (manuStr, 0x00, sizeof(manuStr));
memset (prodStr, 0x00, sizeof(prodStr));
// allocate mcp2200_{manu,prod}_string buffer, 2-dim array with 16 x 16 chars
if (( mcp2200_manu_string = ( unsigned char** )malloc( 16*sizeof( unsigned char* ))) == NULL ) {
// error
}
if (( mcp2200_prod_string = ( unsigned char** )malloc( 16*sizeof( unsigned char* ))) == NULL ) {
// error
}
for ( i = 0; i < 16; i++ )
{
if (( mcp2200_manu_string[i] = ( unsigned char* )malloc( 16 )) == NULL ) {
/* error */
}
if (( mcp2200_prod_string[i] = ( unsigned char* )malloc( 16 )) == NULL ) {
/* error */
}
/* init the rows here */
memset (mcp2200_manu_string[i], 0x00, sizeof(&mcp2200_manu_string[i]));
memset (mcp2200_prod_string[i], 0x00, sizeof(&mcp2200_prod_string[i]));
}
// manuStr holds (strlen(manuStr) * 2) + 2 in byte[0] and manufacturer string from byte[1] on
strcpy (&manuStr[1], manu);
manuStr[0] = ((strlen (&manuStr[1]) * 2) + 2);
// prodStr holds (strlen(prodStr) * 2) + 2 in byte[0] and product string from byte[1] on
strcpy (&prodStr[1], prod);
prodStr[0] = ((strlen (&prodStr[1]) * 2) + 2);
// build manufacturer / product strings
for (i=0, k=0; i<16; i++, k+=4) {
if (i==0) {
tmp = 0x03;
} else {
tmp = 0x00;
}
// manufacturer string
mcp2200_manu_string[i][0] = MCP2200_SECRET_CONFIGURE;
mcp2200_manu_string[i][1] = MCP2200_CFG_MANU;
mcp2200_manu_string[i][2] = i;
mcp2200_manu_string[i][3] = manuStr[k];
mcp2200_manu_string[i][4] = tmp;
mcp2200_manu_string[i][5] = manuStr[k+1];
mcp2200_manu_string[i][6] = 0x00;
mcp2200_manu_string[i][7] = manuStr[k+2];
mcp2200_manu_string[i][8] = 0x00;
mcp2200_manu_string[i][9] = manuStr[k+3];
mcp2200_manu_string[i][10] = 0x00;
mcp2200_manu_string[i][11] = 0xff;
mcp2200_manu_string[i][12] = 0xff;
mcp2200_manu_string[i][13] = 0xff;
mcp2200_manu_string[i][14] = 0xff;
mcp2200_manu_string[i][15] = 0xff;
// product string
mcp2200_prod_string[i][0] = MCP2200_SECRET_CONFIGURE;
mcp2200_prod_string[i][1] = MCP2200_CFG_PROD;
mcp2200_prod_string[i][2] = i;
mcp2200_prod_string[i][3] = prodStr[k];
mcp2200_prod_string[i][4] = tmp;
mcp2200_prod_string[i][5] = prodStr[k+1];
mcp2200_prod_string[i][6] = 0x00;
mcp2200_prod_string[i][7] = prodStr[k+2];
mcp2200_prod_string[i][8] = 0x00;
mcp2200_prod_string[i][9] = prodStr[k+3];
mcp2200_prod_string[i][10] = 0x00;
mcp2200_prod_string[i][11] = 0xff;
mcp2200_prod_string[i][12] = 0xff;
mcp2200_prod_string[i][13] = 0xff;
mcp2200_prod_string[i][14] = 0xff;
mcp2200_prod_string[i][15] = 0xff;
}
}
Call this function in your main loop:
prepare_cfg_strings ("MyManufacturerName, "MyProductName");
Open a hid handle to your mcp2200 and put this stuff on the bus:
// write manufacturer string configuration to usb device
for (i=0; i<16; i++) {
hid_write (handle, mcp2200_manu_string[i], 16);
}
// write product string configuration to usb device
for (i=0; i<16; i++) {
hid_write (handle, mcp2200_prod_string[i], 16);
}
If you want to flash the mcp2200 with your own VendorID / ProductID configure your message:
// Microchip VID: 0x04d8
// MCP2200 PID: 0x00df
mcp2200_pid_vid_cfg[] = 01 00 D8 04 DF 00 00 00 00 00 00 00 00 00 00 00
| | +---+ +---+--------------------------------> Product ID (bytes swapped)
| | +--------------------------------------> Vendor ID (bytes swapped)
| +--------------------------------------------> MCP2200 Config Bit (MCP2200_CFG_VID_PID)
+-----------------------------------------------> MCP2200_SECRET_CONFIGURE from usb trace
and put it on the bus:
hid_write (handle, mcp2200_pid_vid_cfg, 16);
Have Fun!
n.
You will not be able to control the GPIO ports from the console/terminal via USB tty...
The USB to serial/UART converter is one of the features of MCP2200, to control the GPIO, you need to send commands via USB & HID driver. to achieve this, you will need the following.
HIDAPI:
https://github.com/signal11/hidapi
USBtoUART:
https://github.com/Miceuz/USBtoUART
USBtoUART requires hid.o from the HIDAPI package.... so start with HIDAPI first...
good luck!
MikeF
ps: I made a few modifications to the code, to accept binary format for controlling the GPIO ports, etc... it has been compiled fine on x86 and ARM ( Raspberry Pi )

Resources