The equivelant code %SystemDrive% in batch translated into C++ - c++

To anyone that can help Please,
(My operating system is Windows XP)
I have looked on the this forum but have not found a similair answer that I could use or adapt to suite this particular situation. I will try to explain (I apologise in advance if my question seems confusing)
I am constructing a batch file that will call a C++ program (.exe) The C++ program is hard coded to the C: drive. By the way I did not write the C++ program as I am incapable of writing in C++ but would like to exchange the C: in C++ for what would be in batch %SystemDrive%. The line of code in C++ reads as follows:
SetSfcFileException(0, L"c:\\windows\\system32\\calc.exe",-1);
// Now we can modify the system file in a complete stealth.
}
The bit of code I would like to alter in the above code is C: or "C" to change it to %systemDrive% but in C++ code language, in effect change the hard coded part of the C++ program to read a System path variable within XP.
I have also looked elsewhere on the net but have not found a suitable answer as I do Not want to break the C++ code you see.
The C++ code was obtained from the folowing website written by Abdellatif_El_Khlifi:
https://www.codeproject.com/Articles/14933/A-simple-way-to-hack-Windows-File-Protection-WFP-u
Many Thanks for any help given,
David

The search term you should be looking for is Known Folders.
Specifically, calling SHGetKnownFolderPath() with the FOLDERID_System identifier, one of the many IDs found here.
That's for Vista or better. For earlier than that (such as XP), you have to use CSIDL values, CSIDL_SYSTEM (see here for list) passed into SHGetFolderPath().
You can still use the pre-Vista ones but I think they're just thin wrappers around the newer ones.
This is the simplest console application I could come up with that shows this in action (Visual Studio 2019):
#include <iostream>
#include <shlobj_core.h>
#include <comutil.h>
int main()
{
PWSTR path = NULL;
HRESULT hr = SHGetKnownFolderPath(FOLDERID_System, 0, NULL, &path);
_bstr_t bstrPath(path);
std::string strPath((char*)bstrPath);
std::cout << "Path is '" << strPath << "'\n";
}
and the output on my system is:
Path is 'C:\WINDOWS\system32'

This is not really answering my own question, well it is but in a alternative manner, many ways to skin a cat so to speak!
Here is one encouraging bit of news though I have stumbled across the very thing I need called WFPReplacer, it is a commandline windows utility that pretty well does what I want & generally in the same manner. it disables WFP for both singular files & can be used for wholesale switching off of WFP if the right file is replaced. All I need to do is write a batch file as a front end to back up the system files I want to disable use WFPReplacer.exe. So if in the event of the proceedings the routine gets stuffed I can revert back to the backed up files. I think this program uses the same type of embedded coding but is written in Delphi/pascal, it is called Remko Weijnen's Blog (Remko's Blog) "replacing Wfp protected files".
I generally like to leave whatever I am doing on a positive note. So just in case someone else lands on this forum & is trying to accomplish a similair exercise here is the code that one can compile (This is not my code it belongs to Remko Weijnen's Blog (Remko's Blog)) Please be advised it is NOT C++ it is a commandline exe Delhi/Pascal found at this link, so all credits belong to him. The link is:
https://www.remkoweijnen.nl/blog/2012/12/05/replacing-wfp-protected-files/
DWORD __stdcall SfcFileException(RPC_BINDING_HANDLE hServer, LPCWSTR lpSrc, int Unknown)
{
RPC_BINDING_HANDLE hServerVar; // eax#2
int nts; // eax#6
__int32 dwResult; // eax#7
DWORD dwResultVar; // esi#9
int v8; // [sp+8h] [bp-8h]#1
int v9; // [sp+Ch] [bp-4h]#1
LOWORD(v8) = 0;
*(int *)((char *)&v8 + 2) = 0;
HIWORD(v9) = 0;
if ( !hServer )
{
hServerVar = _pRpcHandle;
if ( !_pRpcHandle )
{
hServerVar = SfcConnectToServer(0);
_pRpcHandle = hServerVar;
if ( !hServerVar )
return 0x6BA; // RPC_S_SERVER_UNAVAILABLE
}
hServer = hServerVar;
}
nts = SfcRedirectPath(lpSrc, (int)&v8);
if ( nts >= 0 )
dwResult = SfcCli_FileException((int)hServer, v9, Unknown).Simple;
else
dwResult = RtlNtStatusToDosError(nts);
dwResultVar = dwResult;
MemFree(v9);
return dwResultVar;
}
Also as one further warning (Unless you know what you are doing!!!) do not attempt to use this program, ALWAYS ALWAYS ALWAYS backup your system files before deletion or alteration.
What this program will do is disarm WFP for 60 seconds whilst you intercange or amend your files. Example usage for example is:
WfpReplacer.exe c:\windows\Notepad.exe (Errorlevel true or false will be produced on execution).
Best Regards
David

Related

rollback function or design pattern in C++

Right now, I am facing a new problem that I can't figure out how to fix. I have two files. One is a video file and other is a thumbnail. They have same name. I want to rename these two files using C++. I am using the rename function and it works. This is what I've written:
if(rename(videoFile) == 0)
{
if(rename(thumbnail) != 0)
{
printf("Fail rename \n");
}
}
The problem occurs when the video file is renamed successfully but for some reason the thumbnail can't be renamed. When this happens, I would like to rollback the renaming of the video file because the video file name and the thumbnail file name should be the same in my program. What I want to do is to rename after both files are okay to rename. Please guide me, any design pattern for function like rollback or third party software.
There is no absolutely foolproof way to do this.
Fundamental rule of disk I/O: The filesystem can change at any time. You can't check whether a rename would succeed; your answer is already wrong. You can't be certain that undoing the rename will succeed; somebody else might have taken the name while you briefly weren't using it.
On systems that support hard links, you can use them to get about 90% of the way there, assuming you're not moving between filesystems. Suppose you're renaming A to B and C to D. Then do these things:
Create hard link B which links to A. This is written as link("A", "B") in C, using the Unix link(2) system call. Windows users should call CreateHardLink() instead.
If (1) succeeded, create hard link D which links to C. Otherwise, return failure now.
If (2) succeeded, delete A and C and return success. Otherwise, delete B and return failure. If the deletions fail, there is no obvious means of recovery. In practice, you can probably ignore failed deletions assuming the reason for failure was "file not found" or equivalent for your platform.
This is still vulnerable to race conditions if someone deletes one of the files out from under you at the wrong time, but that is arguably not an issue since it is largely equivalent to the rename failing (or succeeding) and then the person deleting the file afterwards.
Technically, you should also be opening the containing directory (in O_RDONLY mode) and fsync(2)'ing it after each operation, at least under Unix. If moving between directories, that's both the source and the destination directories. In practice, nobody does this, particularly since it will lead to degraded performance under ext3. Linus takes the position that the filesystem ought to DTRT without this call, but it is formally required under POSIX. As for Windows, I've been unable to find any authoritative reference on this issue on MSDN or elsewhere. So far as I'm aware, Windows does not provide an API for synchronizing directory entries (you can't open() a directory, so you can't get a file descriptor suitable to pass to fsync()).
Nitpick: To some extent, this sort of thing can be done perfectly on transactional filesystems, but just about the only one in common use right now is NTFS, and Microsoft specifically tells developers not to use that feature. If/when btrfs hits stable, transactions might become genuinely useful.
On Windows platform starting from Vista, you can use code such as the following.
#include "KtmW32.h"
bool RenameFileTransact( LPCTSTR lpctszOldVideoFile, LPCTSTR lpctszNewVideoFile, LPCTSTR lpctszOldThumbnailFile, LPCTSTR lpctszNewThumbnailFile )
{
bool bReturn = false;
HANDLE hRnameTransaction = CreateTransaction(NULL, NULL, 0, 0, 0, 0, NULL);
if (MoveFileTransacted(lpctszOldVideoFile, lpctszNewVideoFile, NULL, NULL, 0, hRnameTransaction) &&
MoveFileTransacted(lpctszOldThumbnailFile, lpctszNewThumbnailFile, NULL, NULL, 0, hRnameTransaction))
{
if ( CommitTransaction(hRnameTransaction))
{
bReturn = true;
}
}
CloseHandle( hRnameTransaction );
return bReturn;
}
But as #Kevin pointed out above, Microsoft discourages the usage of this good feature.

CreateProcess and CreatePipe to execute a process and return output as a string in VC++

I am trying to use CreateProcess and CreatePipe to execute a process from within a Windows Forms C++/CLR application in Visual Studio 2010.
From within my Windows forms app I want to execute a child process (console app) and return the output as a std::string, std::wstring, or System::String^ within my Windows forms app. Additionally, I do not want the newly created child process to spawn a window.
The console application is of my own creation, so I have control of it's source too.
I have seen the following examples, but I do not understand how to modify the code to accomplish what I am trying to do:
MSDN
kgui
A simpler MFC based function
The MSDN code appears to be written as two console apps, one calling the other. The code is confusing to me. I've only been working in C++ for about 4 months, so I still don't understand everything. It appears to reference a text file, which I don't need to do.
Is there a simpler way to do this than MSDN's 200+ lines of code or kgui's 300+ lines of code?
The answer here was helpful, but over simplistic. I was hoping to see a basic source example (one that doesn't involve hundreds of lines of complex code would be preferable). I would have used the MFC code, but I had difficulty adapting it to my purposes (I'm not using MFC).
Following is my adaptation of the code from Code Project:
string ExecuteExternalFile(string csExeName, string csArguments)
{
string csExecute;
csExecute=csExeName + " " + csArguments;
SECURITY_ATTRIBUTES secattr;
ZeroMemory(&secattr,sizeof(secattr));
secattr.nLength = sizeof(secattr);
secattr.bInheritHandle = TRUE;
HANDLE rPipe, wPipe;
//Create pipes to write and read data
CreatePipe(&rPipe,&wPipe,&secattr,0);
//
STARTUPINFO sInfo;
ZeroMemory(&sInfo,sizeof(sInfo));
PROCESS_INFORMATION pInfo;
ZeroMemory(&pInfo,sizeof(pInfo));
sInfo.cb=sizeof(sInfo);
sInfo.dwFlags=STARTF_USESTDHANDLES;
sInfo.hStdInput=NULL;
sInfo.hStdOutput=wPipe;
sInfo.hStdError=wPipe;
//Create the process here.
CreateProcess(0,(LPWSTR)csExecute.c_str(),0,0,TRUE,NORMAL_PRIORITY_CLASS|CREATE_NO_WINDOW,0,0,&sInfo,&pInfo);
CloseHandle(wPipe);
//now read the output pipe here.
char buf[100];
DWORD reDword;
string m_csOutput,csTemp;
BOOL res;
do
{
res=::ReadFile(rPipe,buf,100,&reDword,0);
csTemp=buf;
m_csOutput+=csTemp;
}while(res);
return m_csOutput;
}
I have tried using this from within my Windows Forms app, and while it compiles ok and doesn't cause any errors, it doesn't seem to work either. I have no idea why.
This is how I executed the above code:
std::string ping = ExecuteExternalFile("ping.exe", "127.0.0.1");
It did not appear to do anything, except that on the first execution it give a very strange 3 characters as an output, then on subsequent executions, nothing.
You are not making correct use of the ::ReadFile() function.
Read about it here: http://msdn.microsoft.com/en-us/library/ms891445.aspx
Basically, you want to fail with an error if the function ever does not return TRUE, and you want to keep looping until it yields a zero reDword.
Also, ::ReadFile() will not zero-terminate your data for you, so you have to do it yourself, like this: buf[reDword] = '\0'; (make sure your buf is 101 chars long before doing that.)
EDIT:
Since I was asked to provide some example code, here it is, though I have not gone through the trouble of actually compiling it to make sure it works, so please beware of syntax errors, and generally consider it only as a rough pointer to the direction in which it should be done:
#define BUFFER_SIZE 100
string csoutput;
for( ;; )
{
char buf[BUFFER_SIZE+1];
DWORD redword;
if( !::ReadFile(rPipe,buf,BUFFER_SIZE,&redword,0) )
{
DWORD error = ::GetLastError();
//throw new Exception( "Error " + error ); //or something similar
}
if( redword == 0 )
break;
buf[redword] = '\0';
string cstemp = buf;
csoutput += cstemp;
}
return csoutput;
Thanks to Hans Passant for the lead that got me to this clear and simple piece of code that does exactly what I was looking for.
/// this namespace call is necessary for the rest of the code to work
using namespace System::Diagnostics;
using namespace System::Text;/// added for encoding
Process^ myprocess = gcnew Process;
Encoding^ Encoding;/// added for encoding
Encoding->GetEncoding(GetOEMCP());/// added for encoding
myprocess->StartInfo->FileName = "ping.exe";
myprocess->StartInfo->Arguments = "127.0.0.1";
myprocess->StartInfo->UseShellExecute = false;
/// added the next line to keep a new window from opening
myprocess->StartInfo->CreateNoWindow = true;
myprocess->StartInfo->RedirectStandardOutput = true;
myprocess->StartInfo->StandardOutputEncoding = Encoding;/// added for encoding
myprocess->Start();
String^ output = gcnew String( myprocess->StandardOutput->ReadToEnd() );
myprocess->WaitForExit();
/// OutputBox is the name of a Windows Forms text box in my app.
OutputBox->Text = output;
EDIT: Added encoding information. See above code.

On the fly font coloring in Tclsh via c++

I am an amateur try to hack together a little project. It is a simple note storage and retrieval console app on Windows Vista (and XP - i'm hoping to run the whole thing off a USB Stick).
I use Sqlite as the store and Tcl/SQL scripts to add notes (and tags!) and also retrieve them by tag. 3 tables and a "Toxi" schema.
So anyway... I want to use it from either a "dos prompt" or more frequently tclsh (NOT wish!) I don't want the windowing shell or to use TK at all. But to help visually distinguish some things, stdin from stdout, notes from timestamps, etc, I want to change the font color on-the-fly with some kind of crude markup.
I found a c++ project that will do exactly this! Jaded Hobo put it up on: http://www.codeproject.com/script/Articles/ViewDownloads.aspx?aid=9130. Jaded Hobo says the header file "Console.H" is sufficient to include in a c++ project, but he doesn't know TCL.
I found SWIG, the interface compiler, and I'm going to give it a try. But I'm clueless on a few things:
Can just a header file be enough?
The SWIG Win32 examples aren't as edifying as the 'nix example and they use MS VC++ (VStudio)- I want to use Quincy/MinGW.
(Oh, btw this is my first ever attempt at using C of any kind. So can you show how to use SWIG with Quincy?)
How can I glean from the header source just what the heck to type in my Tcl script to use it?
Thank you for reading this, let alone answering. I started to put it on comp.lang.tcl but I don't like my email addr broadcast like that.
A header isn't enough by itself. On the other hand, you really don't need to go to all that much work since this page indicates that the API is actually really simple. Here's the C code that you need:
#include <tcl.h>
#include <windows.h>
static int MySetConsoleColorCmd(
ClientData clientData, Tcl_Interp *interp,
int objc, Tcl_Obj *const objv[])
{
HANDLE hConsole;
int code;
/* Parse arguments, first for argument count, then for number format */
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, "colorCode");
return TCL_ERROR;
} else if (Tcl_GetIntFromObj(interp, objv[1], &code) != TCL_OK) {
return TCL_ERROR;
}
/* Get console handle, checking for the error case */
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
if (hConsole == INVALID_HANDLE_VALUE) {
Tcl_SetResult(interp, "not a console application", TCL_STATIC);
return TCL_ERROR;
}
/* Set the color! */
SetConsoleTextAttribute(hConsole, code);
return TCL_OK;
}
/* Standard entry point for loadable library */
int Consolecolor_Init(Tcl_Interp *interp) {
Tcl_CreateObjCommand(interp, "consolecolor", MySetConsoleColorCmd,
NULL, NULL);
return TCL_OK;
}
Compile this up into a DLL (it's got no fancy dependencies at all, beyond Tcl itself) called consolecolor.dll (the name should match the entry point function somewhat) and then you'll be able to use the load command to import the new consolecolor command into your code, like this:
load /path/to/consolecolor.dll
# Duplicate example from the page mentioned at the top of this answer
for {set k 1} {$k < 255} {incr k} {
consolecolor $k
puts "$k => I want to be nice today!"
}
For a guide to how to pick colors, see this MSDN page.

Error while reading files with native code on windows mobile

I'm new here and my english is not really good. Apologize any inconvenience!
I'm programming an application for windows mobile with native code (MFC). I'm trying to open a file and this is driving me crazy. I've tried to open it in a thousand diferent ways... And I really achieve it, but when I try to read (fread or getline) the program crashes without any explanation:
The program 'x' finalize with code 0 (0x0)
The GetLastError() method, in some cases, returns me a 183.
Then, I put the code I've used to open the file:
std::wifstream file(L"\\Archivos de programa\\Prog\\properties.ini");
wchar_t lol[100];
if (file) {
if(!file.eof()) {
file.getline(lol,99);
}
}
It enters on all the if's, but the getline crashes.
FILE * lol = NULL;
lol = _wfope n(ruta, L"rb");
DWORD a = GetLastError();
if ( lol != NULL )
return 1;
else
return -1;
It returns 1 (correct), and after, in a later getline, it stores trash on the string. However, it doesn't crash!!
fp.open (ruta, ifstream::in);
if ( fp.is_open() ) {
return 1;
}else{
return -1;
}
It enters on the return 1, but when executing the later getline() crashes.
I've debugged the getline() method and it crashes on the library fstream, right there:
if ((_Meta = fget c (_File)) == EOF)
return (false);
In the if. The fgetc(), I supose.
I'm going completely crazy!! I need some clue, please!!
The path of the file is correct. First, because, in theory, the methods open the file, and second, I obtain the path dinamically and it matches.
Emphasize that the fread method also crashes.
Thanks in advance!
P.S.:
Say that when I do any fopen, the method fp.good() returns me FALSE, and the GetLastError returns me 183. By the other hand, if I use fp.fopen(path, ifstream::in); or std::wifstream fp(path); the fp.good(); returns me TRUE, and the GetLastError() doesn't throw any error (0).
A hint: use the Process Monitor tool to see what goes wrong in the file system calls.
The path accepted by wifstream is lacking a drive ("C:" or the like) (I don't know what the ruta variable points to)
Apart from the streams problem itself, you can save yourself a lot of trouble by using the GetProfileString and related functions, when using a windows .ini file.
I'm shooting in the dark here, but your description sounds like a runtime mismatch story. Check that MFC and your project use the same runtime link model (static/dynamic). If you link to MFC dynamically, then the restriction is stricter: both MFC and your project have to use dynamic runtime.
I don't know why, but with the CFile class... it works...
Programming mysteries!
Shooting in the dark too.
Unexplained random crash in MFC often comes from a mismatch message handler prototype.
For example the following code is wrong but it won't generate any warning during compilation and it may work most of the time :
ON_MESSAGE(WM_LBUTTONDOWN, onClick)
...
void onClick(void) //wrong prototype given the macro used (ON_MESSAGE)
{
//do some stuff
}
Here the prototype should be :
LRESULT onClick(WPARAM, LPARAM)
{
}
It often happens when people get confident enough to start modifying manually the message maps.

How to get serial number for Hard Drive

How to get the unique number (serial number/ID) for Processor (CPU), SCSI, Display, and IDE using C++ program other than WMI and asm code?
Since you mention WMI, I assume you are working on Windows. Lookup GetVolumeInformation().
On Windows you can get CPU info from the environment variable *PROCESSOR_** , you can parse the volume serial number from vol, the MAC address from route print
If you want to make it cross-platform (and if this is for software licensing) then an open source platform like Linux raises the problem to a whole new level anyway and requires a different approach. However you can still get a lot of the info by parsing the output from standard tools.
You really should consider WMI. In the old days, the BIOS would have been helpful but its all been replaced by the HAL.
CodeProject is always worth searching in cases like this.
How To Get Hardware Information
The below is the code I use to retrieve the hard drive serial for a game, so that cheaters are permanently banned (and they can't get back in without getting a new drive!):
string GetMachineID()
{
// LPCTSTR szHD = "C:\\"; // ERROR
string ss;
ss = "Err_StringIsNull";
UCHAR szFileSys[255],
szVolNameBuff[255];
DWORD dwSerial;
DWORD dwMFL;
DWORD dwSysFlags;
int error = 0;
bool success = GetVolumeInformation(LPCTSTR("C:\\"), (LPTSTR)szVolNameBuff,
255, &dwSerial,
&dwMFL, &dwSysFlags,
(LPTSTR)szFileSys,
255);
if (!success) {
ss = "Err_Not_Elevated";
}
std::stringstream errorStream;
errorStream << dwSerial;
return string(errorStream.str().c_str());
}
Although there is a potential bug whereupon if Windows is installed onto a drive other than C:\, this is an easy fix.