|
A few seconds reading of the sysinternals[^] website gives the following explanation of how regmon works:
How Regmon Works
The heart of Regmon on Windows 9x is in the virtual device driver, Regvxd.vxd. It is dynamically loaded,
and in its initialization it uses VxD service hooking (see our May 1996 Dr. Dobb's Journal article on VxD
= service hooking for more information) to insert itself onto the call chain of 16 registry access functions
in the Windows 95 kernel (Virtual Machine Manager). All registry activity, be it from 16-bit programs, Win32
applications, or device drivers, are directed at these routines, so Regmon catches all registry activity
taking place on a machine.
On Windows NT, 2000 and XP the Regmon loads a device driver that uses a technique we pioneered for NT called
system-call hooking. When a user-mode component makes a privileged system call, control is transfered to a
software interrupt handler in NTOSKRNL.EXE (the core of the Windows NT operating system). This handler takes
a system call number, which is passed in a machine register, and indexes into a system service table to find
the address of the NT function that will handle the request. By replacing entries in this table with pointers
to hooking functions, it is possible to intercept and replace, augment, or monitor NT system services.
Regmon, which obviously hooks just the Registry-related services, is merely one example of this capability in
action.
On Windows .NET Server Regmon takes advantage of a new operating system Registry callback mechanism to
register for and receive information about Registry accesses as they occur. When you run Regmon on .NET
Server it loads a version of the Regmon driver utlizing the callbacks.
When Regmon sees an open, create or close call, it updates an internal hash table that serves as the mapping
between key handles and registry path names. Whenever it sees calls that are handle based, it looks up the
handle in the hash table to obtain the full name for display. If a handle-based access references a key
opened before Regmon started, Regmon will fail to find the mapping in it hash table and will simply present
the key's value instead.
Information on accesses is dumped into an ASCII buffer that is periodically copied up to the GUI for it to
print in its listbox.
In short, it cheats, and grabs the information at a very low level. Not for the faint hearted...
Iain.
|
|
|
|
|
thanks
Ask not what your application can do for you,
Ask what you can do for your application
|
|
|
|
|
Visual C++ Dialog Application
I have 6 radio buttons which I need to group as 3 pairs . How do I specify the the pairing ? i.e which radio is with which group . I am finding that actions in pair 3 affect radios in pair 1 ? Please help
|
|
|
|
|
The fisrt button in a group of radio buttons should be marked as group, under the genral settings in the properties dialog. The next item (in tab order) following the last radio button in a group should be marked as group, this signifies the end of one group and the start of the next.
INTP
|
|
|
|
|
thanks but somehow I couldnt get it to work .
Here is the sequence in Tab order
I need 3 pairs of radio buttons
GROUP1
Radio1(group)
Radio2( ungroup)
GROUP2
Radio3(group)
Radio4(ungroup)
GROUP3
Radio5(Group)
Radio6(ungroup)
Still i find that statuses for GROUP1 and GROUP3 are interfering .
still statuses for
|
|
|
|
|
I do not know what else to tell you except what I did to verify my previous answer.
1) I created a new dialogbox.
2) I added 6 radio buttons (nothing else)
3) I checked group on the fallowing items:
radio 1, radio 3, radio 5, and the OK button.
4) I checked tabstop on the fallowing items:
radio 1, radio 3, radio 5.
Now every thing works as it should.
The normal procedure I use for a group of radio buttons goes as follows:
1) Create a group box and check group (not tabstop).
2) Create a group of radio buttons in box and check tabstop on first button.
3) Make sure the tab order of the group box is 1 less than the first button.
INTP
|
|
|
|
|
Hi all,
I experienced a strange behaviour, maybe one of you knows something
about it.
I have a little application that call SHBrowseForFolder, after that it
connects to an SQL server via SQLDriverConnect. After some work it
releases every allocated ODBC handle.
Any subsequent call to SHBrowseForFolder will display an empty dialog,
not even the controls are drawn.
This happens only if there is a manifest file for this application to
use the new common controls.
I included the source code as a sample a little bit more down,
if you would like the complete Devstudio workspace, just email me.
I would be happy if any of you knows something about this,
thanks in advance,
Jens
Source code:
-----------------
#ifndef BIF_NEWDIALOGSTYLE
#define BIF_NEWDIALOGSTYLE 0x0040
#define BIF_USENEWUI (BIF_NEWDIALOGSTYLE | BIF_EDITBOX)
#endif
void Go()
{
// *** Doesn't help...
// ::CoInitialize( 0 );
BROWSEINFO bi;
ZeroMemory( &bi, sizeof( bi ) );
bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS;
SHBrowseForFolder( &bi );
SQLHENV env = NULL;
SQLRETURN sqlRet = SQLAllocEnv( &env );
SQLHDBC conn = NULL;
sqlRet = SQLAllocConnect( env, &conn );
SQLCHAR szOut[ 2048 ] = {0};
SQLCHAR sqlConn[ 1024 ] = "DRIVER={SQL Server};SERVER=(local)";
// SQLCHAR sqlConn[ 1024 ] = "DRIVER={Microsoft Text Driver (*.txt;
*.csv)};DBQ=test\\";
SWORD len = 0;
sqlRet = SQLDriverConnect( conn,
NULL,
sqlConn,
SQL_NTS,
szOut,
sizeof( szOut ),
&len,
SQL_DRIVER_COMPLETE_REQUIRED );
if ( ( SQL_SUCCESS != sqlRet )
&& ( SQL_SUCCESS_WITH_INFO != sqlRet ) )
{
SWORD nMessageLen = 0;
UCHAR szMessage[ SQL_MAX_MESSAGE_LENGTH ] = {0};
SDWORD dwNativeErrorCode = 0;
UCHAR szErrorState[ SQL_SQLSTATE_SIZE + 1 ] = {0};
sqlRet = SQLError( env,
conn,
SQL_NULL_HSTMT,
szErrorState,
&dwNativeErrorCode,
szMessage,
SQL_MAX_MESSAGE_LENGTH - 1,
&nMessageLen );
::MessageBox( NULL,
(CHAR*)szMessage,
(CHAR*)szErrorState,
MB_OK );
}
sqlRet = SQLDisconnect( conn );
sqlRet = SQLFreeHandle( SQL_HANDLE_DBC, conn );
sqlRet = SQLFreeHandle( SQL_HANDLE_ENV, env );
// *** Doesn't help...
// ::CoInitialize( 0 );
ZeroMemory( &bi, sizeof( bi ) );
bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS;
SHBrowseForFolder( &bi );
}
|
|
|
|
|
After the first call to SHBrowseForFolder(), the 'bi' variable is not used again until the end of Go(). Is this intentional? What happens if you remove everything SQL/ODBC related? Does SHBrowseForFolder() work repeatedly then?
|
|
|
|
|
bi is used again in the second call to SHBrowseForFolder.
You could use another instance, that doesn't matter.
SHBrowseForFolder works repeatedly is I remove the call to
"sqlRet = SQLFreeHandle( SQL_HANDLE_ENV, env );"
This happens only with the MS SQL Server ODBC driver.
If another driver is used (MS Text driver, Sybase Anywhere)
it works fine.
Thanks,
Jens
|
|
|
|
|
Jens Doose wrote:
bi is used again in the second call to SHBrowseForFolder.
Right, but's it's still not being used. The code pieces are disparate. The usage of 'bi' and the success/failure of the calls to SHBrowseForFolder() have nothing to do with the SQL-related stuff.
It's considered good practice to check the return values from all function calls. Something like:
void Go( void )
{
BROWSEINFO bi = {0};
SQLRETURN sqlRet
SQLHENV env = NULL;
SQLHDBC conn = NULL;
SWORD len = 0,
nMessageLen = 0;
SQLCHAR szOut[2048] = {0},
sqlConn[1024] = "DRIVER={SQL Server};SERVER=(local)";
UCHAR szMessage[ SQL_MAX_MESSAGE_LENGTH ] = {0},
szErrorState[ SQL_SQLSTATE_SIZE + 1 ] = {0};
SDWORD dwNativeErrorCode = 0;
bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS;
SHBrowseForFolder( &bi );
sqlRet = SQLAllocEnv(&env);
if (SQL_SUCCESS == sqlRet)
{
sqlRet = SQLAllocConnect(env, &conn);
if (SQL_SUCCESS == sqlRet)
{
sqlRet = SQLDriverConnect(conn, NULL, sqlConn, SQL_NTS, szOut, sizeof(szOut), &len, SQL_DRIVER_COMPLETE_REQUIRED);
if (SQL_SUCCESS != sqlRet && SQL_SUCCESS_WITH_INFO != sqlRet)
{
sqlRet = SQLError(env, conn, SQL_NULL_HSTMT, szErrorState, &dwNativeErrorCode, szMessage, SQL_MAX_MESSAGE_LENGTH - 1, &nMessageLen);
::MessageBox(NULL, (CHAR *) szMessage, (CHAR *) szErrorState, MB_OK);
}
sqlRet = SQLDisconnect(conn);
sqlRet = SQLFreeHandle(SQL_HANDLE_DBC, conn);
}
sqlRet = SQLFreeHandle( SQL_HANDLE_ENV, env );
}
ZeroMemory(&bi, sizeof(bi));
bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS;
SHBrowseForFolder(&bi);
}
Jens Doose wrote:
This happens only with the MS SQL Server ODBC driver.
If another driver is used (MS Text driver, Sybase Anywhere)
it works fine.
Or it's just being masked such that it appears fine.
|
|
|
|
|
Hi David,
that is true.
But that was not my point, maybe I didn't make myself clear enough.
The problem is that with Windows XP the second call to SHBrowseForFolder
does not work, either it isn't shown at all (when there is no manifest file)
or the dialog is shown, but it doesn't contain the control, which displays
all the folders (when having a manifest file).
And this problem only occurs when making a SQLDriverConnect to an MS SQL
ODBC driver in between this two calls. Any other driver is fine.
I discovered the problem in a much more complex environment, and believe
me, it did cost me some hours of my life to hunt the problem down to this
constellation .
To clarify the problem I wrote a simple test app that just calls SHBrowseForFolder
and SQLDriverConnect . That is why there is no error checking or why I don't use
the result value within bi .
Thanks
Jens
|
|
|
|
|
Jens Doose wrote:
The problem is that with Windows XP
Have you tried this on another platform to see if it is OS related?
Jens Doose wrote:
That is why there is no error checking or why I don't use
the result value within bi.
That's fine, and is common practice. I just wanted to emphasize that omitting error checking might have been the crux of the problem.
If you commented out both calls to SHBrowseForFolder() , thus leaving only the SQL-related code, can Go() be called repeatedly?
Perhaps after you are done with SHBrowseForFolder() , you should call IMalloc::Free() .
HRESULT hr;
LPMALLOC pMalloc;
LPITEMIDLIST pidlSelected = NULL;
hr = SHGetMalloc(&pMalloc);
pidlSelected = SHBrowseForFolder(&bi);
...
pMalloc->Free(pidlSelected);
|
|
|
|
|
hi,
i have currently written the code for a right click popup menu for a listctrl on a dialog box in the 'OnRightButtonDown' event.
But i want it to handled by the 'OnContextMenu' event.
How can i catch the WM_CONTEXTMENU message ?
Hari Krishnan
|
|
|
|
|
I know.. it's maybe a simple question. How can I use the printer?
I've made a database-application and now I'd like to print some tables but somehow it won't work
It's an MFC-SDI application.
I know that I must edit a DC but I don't know which function I have to use. The app-wizard already made a print-preview. But there must be some functions to override that I can edit the DC and "draw" with my data.
btw. sorry for my bad english
thanks for help.
|
|
|
|
|
Hii All
I have a realy big question
while running my application it crashes on HEeapValidate function
can anyone help me please with this issue ?
10'x
|
|
|
|
|
You've either overrun or underrun a buffer, which has trashed a heap data structure which it uses to keep track of what blocks are allocated and where they are.
I suggest using the PageHeap tool from Microsoft's Application Compatibility Toolkit[^] to turn on the 'full-page heap'. This causes each heap allocation to happen at the end of a memory page, with the next page being reserved as a guard page. As soon as the overrun occurs, your program will get an access violation.
If the problem is an underrun, there's another option for putting the allocation at the beginning of a fresh page and keeping the page before as a guard page.
If the problem is in a C runtime-allocated block (i.e. allocated with malloc() or new ) this won't necessarily show the problem immediately, as the CRT does its own memory allocation. Use the CRTDBG.H facilities to find your problem.
|
|
|
|
|
maybe I will elabrate some more.
the problem is caused from a multithreaded server.
when I use new() or malloc().
as I know allocation of memory should not trash the heap
so how can I know where to start fixing this problem
|
|
|
|
|
We ran into some similar problems -- with a busy multithreaded server... We 'think' that the MS default memory manager doesn't work too well in that environment, and eventually leads to some corruption.
We switched to a commmercial memory manager -- "SmartHeap" -- it's not cheap, but it's quick and comprehensive. Includes built-in debug, catches double deletes, and other stuff.
Check them out at: www.microquill.com
It was worth $$$ in saved time and energy, and servers that don't crash anymore. At least they don't crash for memory allocation errors. I wish MicroQuill would pay me for each time I endorse their product, we are really really pleased with it.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br />
Peter Weyzen<br />
Staff Engineer<br />
<A HREF="http://www.santacruznetworks.com">Santa Cruz Networks</A>
|
|
|
|
|
Your heap is already trashed at the point that you allocate. The heap manager code is trying to find a block that it can give you, but the corrupted block headers prevent it from doing so.
There's some other overrun that's causing this problem.
|
|
|
|
|
I am trying to spin through an array in a struct and for each element in that array I want to get the value of another array in another struct.
The problem I am having is that the value is always the same.
My structs are:
<br />
struct TSimHeader<br />
{<br />
char Name[45][20];<br />
char Unit[45][20];<br />
double Min[45];<br />
double Max[45];<br />
int SignalCount;<br />
int SimStatus;<br />
<br />
}static TSimHeader_arr[10];<br />
<br />
<br />
struct TSimSignal<br />
{<br />
double Value[45];<br />
double TimeStamp;<br />
<br />
}static TSimSignal_arr[10];
My function to match elements in the TSimHeader_arr[0].Name[] array with the same element in the TSimSignal_arr[0].Value[] is:
void Tflight_data::getValues(){<br />
int numSignals = RFMAccess::TSimHeader_arr[0].SignalCount;<br />
<br />
for(int i=0; i<numSignals; i++){<br />
char* temp = RFMAccess::TSimHeader_arr[0].Name[i];<br />
char* temp2 = RFMAccess::TSimHeader_arr[0].Name[i+1];<br />
<br />
if(strcmp(temp, "pla"))<br />
display_pla_level(RFMAccess::TSimSignal_arr[0].Value[i]);<br />
<br />
if(strcmp(temp, "pitch_stickF")&& strcmp(temp2, "roll_stickF")){<br />
roll = (RFMAccess::TSimSignal_arr[0].Value[i] / 10.0);<br />
pitch = (RFMAccess::TSimSignal_arr[0].Value[i+1] / 10.0);<br />
flight_data->fwd_pl->Repaint();<br />
}<br />
if(strcmp(temp, "nose_wow")){<br />
if(RFMAccess::TSimSignal_arr[0].Value[i] != 0)<br />
front_wheel_led->Active = true;<br />
}<br />
if(strcmp(temp, "left_wow")){<br />
if(RFMAccess::TSimSignal_arr[0].Value[i] != 0)<br />
left_wheel_led->Active = true;<br />
}<br />
if(strcmp(temp, "right_wow")){<br />
if(RFMAccess::TSimSignal_arr[0].Value[i] != 0)<br />
right_wheel_led->Active = true;<br />
} <br />
if(strcmp(temp, "pitch_trim"))<br />
pitch_data_lb->Caption = (AnsiString)RFMAccess::TSimSignal_arr[0].Value[i];<br />
<br />
if(strcmp(temp, "roll_trim"))<br />
roll_data_lb->Caption = (AnsiString)RFMAccess::TSimSignal_arr[0].Value[i];<br />
<br />
if(strcmp(temp, "yaw_trim"))<br />
yaw_data_lb->Caption = (AnsiString)RFMAccess::TSimSignal_arr[0].Value[i];<br />
<br />
}<br />
}
The values should be different depending on the word in the char array. It should match with the exact element in the Values array.
Any ideas why I am getting the same value on each if statement?
I hope I explained it well enough.
Thanks,
steven
|
|
|
|
|
Probably because you are always looking at the same offset into the RFMAccess::TSimHeader_arr and RFMAccess::TSimSignal_arr structures - zero!
|
|
|
|
|
see every occurrance of "TSimSignal_arr[0]."
I'd also consider cleaning up your data structures. I've been doing this for 10+ years, and I still can't stand doubly indexed (2d) arrays used for characters.... not intuitive at all.
<br />
struct TSimHeader<br />
{<br />
char Name[45][20];<br />
char Unit[45][20];<br />
double Min[45];<br />
double Max[45];<br />
int SignalCount;<br />
int SimStatus;<br />
}static TSimHeader_arr[10];<br />
<br />
<br />
struct TSimSignal<br />
{<br />
double Value[45];<br />
double TimeStamp;<br />
}static TSimSignal_arr[10];<br />
couldn't this be something more like:
<br />
#define MAX_ENTRIES (45)<br />
#define MAX_ARRAY_SIZE (10)<br />
#define MAX_STRING_SIZE (20)<br />
<br />
struct TSimHeaderEntry<br />
{<br />
char Name[MAX_STRING_SIZE];<br />
char Unit[MAX_STRING_SIZE];<br />
double Min;<br />
double Max;<br />
};<br />
<br />
<br />
struct TSimHeader<br />
{<br />
TSimHeaderEntry Entries[MAX_ENTRIES];<br />
int SignalCount;<br />
int SimStatus;<br />
}static TSimHeader_arr[MAX_ARRAY_SIZE];<br />
<br />
<br />
struct TSimSignal<br />
{<br />
double Value[MAX_ENTRIES];<br />
double TimeStamp;<br />
<br />
}static TSimSignal_arr[MAX_ARRAY_SIZE];<br />
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br />
Peter Weyzen<br />
Staff Engineer<br />
<A HREF="http://www.santacruznetworks.com">Santa Cruz Networks</A>
|
|
|
|
|
strcmp() returns 0 if the strings are the same, non-zero if they are different. Your if statements will always be executed if the strings are not the same, which I assume is the majority of times. It looks like you want the if statements to be executed if the strings are equal, so you'll need to modify them like this:
if(strcmp(temp, "pla") == 0) etc...
Hope this helps,
Ryan "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"
|
|
|
|
|
I would like to query my monitor for its EDID data. From another thread here I got an advice to communicate directly with my video card (since there's no Windows API call for querying the EDID, only in the DDK), but I don't know how to use the nvidia driver's functions in my code.
I thought there was a lib or a dll which I had to link into my code and a .h file which contains the name of the functions included in the lib or dll. I've downloaded the nvsdk which contains everything from openGL to directX but there's nothing there I could use.
I've also checked NVidia's developer site, but I haven't found any valuable info regarding my problem.
Any ideas?
|
|
|
|
|
well.. in a program i have got a lot of functions like these (it is function based, so no chance in using a class [would be my first idea to solce this problem])
fun2;
fun3;
void fun1(int i)
{
if(i == 0)
fun2();
else
fun3();
}
well.. now there are a lot of fun2's and fun3's so there are a lot of fun1's too..
is there any neat solution doing this with templates ?
thanks for your help,
bernhard
"I'm from the South Bronx, and I don't care what you say: those cows look dangerous." U.S. Secretary of State Colin Powell at George Bush's ranch in Texas
|
|
|
|
|