|
I wish to read and write NTFS extended file attributes in C++.
I was very surprised that I did not find this information readily available.
First I am assuming that NTFS extended file attributes are name-value pairs of
strings. Is this correct? May I create a name and a value and attach that to
a file as an extended file attribute?
Presuming that that is correct, how do I
1) Determine whether a file supports extended file attributes (resides
on a NTFS drive)
2) Read the extended file attributes
3) Set the extended file attributes
I am in a VC++ 6 environment.
Thanks
|
|
|
|
|
gokings wrote:
...NTFS extended file attributes...
Just so we are on the same page here, what is your definition of "NTFS extended file attributes."
"When I was born I was so surprised that I didn't talk for a year and a half." - Gracie Allen
|
|
|
|
|
GetVolumeInformation() will tell you if the driver is NTFS.
GetFileSecurity() can also tell you, if it fails you're not on NTFS and will get the "Security Information" if this is what you mean by extended.
GetFileAttributes() works on basic FAT r/w/h/s attributes.
GetFileAttributesEx() gets a few more attributes.
GetFileInformationByHandle() gets a bunch of crap.
Or are you talking about "extended attributes" as in:
Extended Attribute Information
Used by file servers that are linked with OS/2 systems. This attribute type isn't useful to Windows NT.
Extended Attributes
Used by file servers that are linked with OS/2 systems. This attribute type
|
|
|
|
|
Thanks for the info!
I have found that NTFS does not support extended attributes in the sense that OS/2 does (unfortunately, in my opinion).
However, it does support multiple data streams. Normally, the default (unnamed) data stream is accessed.
I can use a named data stream to achieve my purpose, though I have to jump through a few hoops.
Thanks for the feedback!
|
|
|
|
|
How can I get the program folder?
|
|
|
|
|
I don't know if there's an actual API call on this or not, but you can always pluck this out of the registry. It's always in the same place on any version of Windows:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\ProgramFilesDir
-OBRon
|
|
|
|
|
Thanks,
I think it will work but it will be more code but thats ok.
|
|
|
|
|
Do you mean the program files folder? or the folder that your program is running from?
Tom Wright
tawright915@yahoo.com
|
|
|
|
|
The Program files folder.
|
|
|
|
|
The problem is that the program files folder can be on several drives. I have MS office installed on my D drive and the installer created a program files folder by default. You'd have to search all fixed drives to make sure that it does not exists on any of them.
Tom Wright
tawright915@yahoo.com
|
|
|
|
|
Have you tried looking at the SHGetFolderPath(), SHGetFolderLocation(), SH* functions?
|
|
|
|
|
GetModuleFileName()
"You're obviously a superstar." - Christian Graus about me - 12 Feb '03
"Obviously ??? You're definitely a superstar!!!" mYkel - 21 Jun '04
Within you lies the power for good - Use it!
|
|
|
|
|
Im trying to setup my app so that when a user right clicks on a associated file type then selects "run with myApp" itll open my app passing the files full path. Ive tried getCommandLine() and directly accessing m_lpCmdLine but both of these return the short file name.
|
|
|
|
|
I'm not certain how do do exactly what you want, but couldn't you call GetLongPathName function once you know the short filename and convert it to the long name?
|
|
|
|
|
Unless he's calling a "short file name" just the "file name" as in x.exe. I've seen this that sometimes you get a full path in the command line and sometimes you just get the exe name.
If you want to get the path to the current executable, which is what you want? You don't want to trust the command line.
To get the path to the location of the exectuable (or DLL) use "GetModuleFileName" or "GetModuleFileNameEx". Those should get you the path to the executable.
|
|
|
|
|
Thank you very much! GetLongPathName was exactly what i needed.
Just out of curiosity, do you have any idea why id be getting a short filename? I manually setup the registry so that when someone right clicked on the file type it ran my program and passed the file as a parameter. Whenever my program would get the command line data itd be in the form:
<long path="" as="" i="" specified="" in="" the="" registry=""> <short path="" of="" the="" file="" selected="">
and by short path i mean the old school dos type w/ ~'s in the path
|
|
|
|
|
Glad the workaround worked for you. I'm sorry I don't know the proper way to do this...I haven't done any shell programming at all. I did find this article on the codeguru; not that I recommend or endorse the codeguru in any way - seeing that I'm a loyal codeproject user:
http://www.codeguru.com/Cpp/COM-Tech/shell/article.php/c1315/
|
|
|
|
|
Hi, I'm currently using Visual Studio .NET 7.0. But some of the new projects I download are made for just 7.1, and I was wondering if it was possible to update 7.0 to 7.1 in the first place?
Thanks
|
|
|
|
|
|
Hi
Here is my Full code in which i am creating a thread in DLL and passing the function name as ThreadFunc . But it is not going to the ThreadFunc after creating it. See the Func PrepareThread() below
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
extern "C" __declspec(dllexport) BOOL Connect ( char *pPort , char *pBuff )
{
int nDataSize = 0;
int nSentSize = 0;
if(strcmp(pPort,"") == 0)
{
strcpy(pBuff,"Please supply a COM port");
return false;
}
g_hPort = Rs232Open(pPort);
if ( l_bTaskAbort )
{
Rs232CleanUp(FALSE);
return false;
}
if ( g_hPort == NULL )
{
l_dwErrCode = GetLastError();
ShowRegError(l_dwErrCode);
Rs232CleanUp(FALSE);
return false;
}
// wake up printer
char wakeUpChars[2];
wakeUpChars[0]=(char)'0x0H';
wakeUpChars[1]='\0';
nDataSize = strlen(wakeUpChars);
nSentSize = Rs232SendBlk(g_hPort, wakeUpChars, nDataSize);
Sleep(100);
if ( l_bTaskAbort )
{
Rs232CleanUp(FALSE);
return(false);
}
//Lets check for oneil printer attached or not
nDataSize = 6;
nSentSize = Rs232SendBlk(g_hPort,"\x1b{ST?}",nDataSize);
if(nSentSize != nDataSize)
return false;
// Sleep(100);
char szData[36];
memset(szData,0x00,sizeof(szData));
if(Rs232RecvBlk(g_hPort,szData,35 ) >0)
{
if(strncmp(szData,"{ST!E:N;",8) != 0)
{
strcpy(pBuff,"Printer is not connected.");
return false;
}
}
else
{
strcpy(pBuff,"Printer is not connected.");
return false;
}
return true;
}
extern "C" __declspec(dllexport) BOOL ReadCard(char *pData)
{
if(g_hPort == NULL)
{
strcpy(pData,"COM port is not opened");
return false;
}
PrepareThread();
return true;
}
extern "C" __declspec(dllexport)void Disconnect()
{
//Terminate Read thread and close msr3000
TerminateThread(g_hThreadRead, 0);
g_hThreadRead = NULL;
Rs232CleanUp(FALSE);
}
DWORD WINAPI ThreadFunc(LPVOID param)
{
BOOL bSuccess = TRUE;
while(1)
{
int index = 0;
// Clear the dara buffer first.
memset(g_strResult,0x00,500);
if ( l_bTaskAbort )
{
Disconnect();
return(false);
}
//if card is seated
// Ask the user to remove the card
// if the card is removed then read the data
if(GetCardData())
{
//MyMSR_ShowResult(0);
break;
}
}
return bSuccess;
}
static void PrepareThread()
{
g_hThreadRead = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadFunc, 0, 0,&dwThreadID);
}
static BOOL GetCardData()
{
BOOL bSuccess = TRUE;
char szData[100];
int nDataSize = 0;
int nSentSize = 0;
DWORD dwStartTime;
dwStartTime = GetTickCount();
szData[0] = 0x1B;
szData[1]='{';
szData[2]='M';
szData[3]='R';
szData[4]='?';
szData[5]='}';
szData[6]='\0';
nDataSize = strlen(szData);
while ( !l_bTaskAbort )
{
DWORD dwEllapsedTime = GetTickCount() - dwStartTime;
//time out
if ( dwEllapsedTime >= READTIMEOUT )
{
bSuccess = FALSE;
break;
}
nSentSize = Rs232SendBlk(g_hPort, szData, nDataSize);
if ( nSentSize != nDataSize )
{
bSuccess = FALSE;
break;
}
Sleep(100);
if( Rs232RecvBlk(g_hPort, g_strResult, 500) >0)
{
// No card data
if(strncmp(g_strResult,"{N}",3) == 0)
{
Sleep(10);
}
else
{
break;
}
}
else
{
Sleep(10);
}
}
return bSuccess;
}
//----------------------------------------------------------------------------
// Rs232Open
//----------------------------------------------------------------------------
static HANDLE Rs232Open(char *pPort)
{
DCB PortDCB;
HANDLE hPort;
BOOL bSuccess = FALSE;
COMMTIMEOUTS CommTimeouts;
PortDCB.DCBlength = sizeof(DCB);
hPort = CreateFile(pPort,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
if ( hPort == INVALID_HANDLE_VALUE )
{
l_dwErrCode = GetLastError();
return NULL;
}
// set up detail
SetupComm(hPort,INQUEUESIZE,OUTQUEUESIZE);
bSuccess = GetCommState(hPort,&PortDCB);
if (bSuccess == FALSE)
{
l_dwErrCode = ERROR_NOT_READY;
CloseHandle(hPort);
//if (g_hStatus != NULL)
// SetWindowText(g_hStatus, TEXT("Err setting Comm"));
return NULL;
}
//CBR_9600, CBR_19200,CBR_38400,CBR_57600,CBR_115200
PortDCB.BaudRate = CBR_9600;
PortDCB.fBinary = TRUE;
PortDCB.fParity = TRUE;
PortDCB.fOutxCtsFlow = FALSE;
PortDCB.fOutxDsrFlow = FALSE;
PortDCB.fDtrControl = DTR_CONTROL_ENABLE;
PortDCB.fDsrSensitivity = FALSE;
PortDCB.fTXContinueOnXoff = TRUE;
PortDCB.fOutX = FALSE;
PortDCB.fInX = FALSE;
PortDCB.fErrorChar = FALSE;
PortDCB.fNull = FALSE;
PortDCB.fAbortOnError = FALSE;
PortDCB.ByteSize = 8;
PortDCB.Parity = NOPARITY;
PortDCB.StopBits = ONESTOPBIT;
PortDCB.fRtsControl = RTS_CONTROL_ENABLE;
PortDCB.XoffLim = INQUEUESIZE/5;
PortDCB.XonLim = INQUEUESIZE/5;
bSuccess = SetCommState(hPort,&PortDCB);
// set time out
bSuccess = GetCommTimeouts(hPort,&CommTimeouts);
CommTimeouts.ReadIntervalTimeout = MAXDWORD;
CommTimeouts.ReadTotalTimeoutMultiplier = 0;
CommTimeouts.ReadTotalTimeoutConstant = 0;
CommTimeouts.WriteTotalTimeoutMultiplier = 0;
CommTimeouts.WriteTotalTimeoutConstant = 3000;
bSuccess = SetCommTimeouts(hPort,&CommTimeouts);
if ( l_bTaskAbort )
{
l_dwErrCode = ERROR_NOT_READY;
CloseHandle(hPort);
// if (g_hStatus != NULL)
// SetWindowText(g_hStatus, TEXT("Err setting timeout"));
return(NULL);
}
Sleep(1000);
PurgeComm(hPort,PURGE_TXCLEAR|PURGE_RXCLEAR);
return(hPort);
}
//----------------------------------------------------------------------------
// Rs232SendBlk
//----------------------------------------------------------------------------
static int Rs232SendBlk(HANDLE hPort, LPSTR lpcData, int nSize)
{
int nLen = 0;
DWORD dwWrite;
l_dwErrCode = ERROR_SUCCESS;
while ( ( nLen < nSize ) && !l_bTaskAbort )
{
if ( !WriteFile(g_hPort,lpcData+nLen,nSize-nLen,&dwWrite,0) )
{
l_dwErrCode = GetLastError();
dwWrite = 0;
}
if ( dwWrite == 0 )
{
break;
}
nLen += dwWrite;
}
return(nLen);
}
//----------------------------------------------------------------------------
// Rs232RecvBlk
//----------------------------------------------------------------------------
static int Rs232RecvBlk(HANDLE hPort, LPSTR lpcData, int nSize)
{
int nLen = 0;
DWORD dwRead;
DWORD dwStartTime;
l_dwErrCode = ERROR_SUCCESS;
dwStartTime = GetTickCount();
while ( ( nLen < nSize ) && !l_bTaskAbort )
{
DWORD dwEllapsedTime = GetTickCount() - dwStartTime;
if ( dwEllapsedTime >= l_dwTimeout )
{
return(nLen);
}
if ( !ReadFile(g_hPort,lpcData+nLen,nSize-nLen,&dwRead,0) )
{
l_dwErrCode = GetLastError();
dwRead = 0;
}
if ( dwRead > 0 )
{
nLen += dwRead;
dwStartTime = GetTickCount();
}
else
{
Sleep(10);
}
}
return(nLen);
}
//----------------------------------------------------------------------------
// Rs232CleanUp
//----------------------------------------------------------------------------
static int Rs232CleanUp(BOOL bSuccess)
{
//l_bTaskAbort = TRUE;
// If there is an open port
if ( g_hPort != NULL )
{
PurgeComm(g_hPort,PURGE_TXABORT|PURGE_TXCLEAR|PURGE_RXABORT|PURGE_RXCLEAR);
// Close the port
CloseHandle(g_hPort);
// Mark it not open
g_hPort = NULL;
}
// Indicate that Rs232 shutdown is complete
l_bTaskDone = TRUE;
// Return what was passed in
return(bSuccess);
}
void ShowRegError(DWORD nReturnVal)
{
LPVOID lpMsgBuf;
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
nReturnVal,
0, // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
MessageBox( NULL, (LPCTSTR)lpMsgBuf, TEXT("Error"), MB_OK | MB_ICONINFORMATION );
// Free the buffer.
LocalFree( lpMsgBuf );
}
|
|
|
|
|
You'll get much more favorable responses by providing only relevant code. No one likes spending their time wading through code that is not part of the problem.
How are you verifying that ThreadFunc() is not being called?
"When I was born I was so surprised that I didn't talk for a year and a half." - Gracie Allen
|
|
|
|
|
I am putting the Break Point in the ThreadFunc() but it is not going to that function.
Shailesh
|
|
|
|
|
aman2006 wrote:
I am putting the Break Point in the ThreadFunc()
On the BOOL bSuccess = TRUE statement, I assume? If so, could it be possible that the primary thread is terminating before the secondary thread has had a chance to start up?
"When I was born I was so surprised that I didn't talk for a year and a half." - Gracie Allen
|
|
|
|
|
I want to write one function in which I want to pass Computer Domain, Account Name, Password and absolute path of any one directory or file. From this four parameters I want to find out whether the entered user has privileges to get content of given file or directory or he is impersonating other user or such things...
Can any one help me ...Any function that you think will be helpful to me or any link which contain such similar example or any material to read ...plz I m waiting eagrly for it..
Thanking You
Chuy Ji Lee.
|
|
|
|
|
You want to do this on NTFS?
Security is a big pain, but this is what I think you have to do.
First, you need to get the security descriptor (The DACL is what you want I think) of the file. You can do this with "GetFileSecurity".
Then you need to have an access token of the client. If this is an RPC call, the user has already called in this context. You can call like "ImpersonateUser()" and then get the user's token with GetToken or something I forget the function, and you can then use one of the "AccessCheck" functions to check if that user has access. You can also call "LogonUser" since you have the password and username to get the user's token I believe. Those are the functions I'm pretty sure you want to look into.
|
|
|
|