按MSDN:ms-help://MS.MSDNQTR.2003FEB.2052/debug/base/registereventsource.htm里的说法,
RegisterEventSource这个函数测试注册表中 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\EventLog\Application\这个键下是否有某个指定的子键,
例如,如果HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\
EventLog\Application\WinApp这个键值存在的话,那么代码
h = RegisterEventSource(NULL, // uses local computer
TEXT("WinApp")); // source name
应该返回一个有效的句柄值。MSDN的部分原文:
For example, WinApp is a valid source name if the registry has the following key:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\
EventLog\Application\WinApp但是我和几个朋友的机器上测试,结果却大不相同我的机器上的测试代码段
HANDLE h;
if ((h = RegisterEventSource(NULL,TEXT("SnortService"))) == NULL){
cout<<GetLastError()<<endl;
cout<<"not exist!"<<endl;
}
结果,无论我输入的子键值存在不存在,h均为NULL,
我的系统为中文2000 server+SP4七猫兄的测试代码段和我一样,但结果正常,如果子键存在,则h不为空,子键不存在,则h== hull,他的机器为中文2003 server猎狐兄的测试代码段如下
HANDLE h;
LPCTSTR s="134";
if ((h =RegisterEventSource(NULL,s)) == NULL){
AfxMessageBox("No Result");
}
测试结果更有意思:无论子键是否存在,h均不为空,和我的正好相反:-),猎狐兄的机器是日文2000
不知道这算不算微软的BUG,希望有条件的朋友也帮着测试一下,然后把结果和你的机器配置发上来,谢谢!
RegisterEventSource这个函数测试注册表中 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\EventLog\Application\这个键下是否有某个指定的子键,
例如,如果HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\
EventLog\Application\WinApp这个键值存在的话,那么代码
h = RegisterEventSource(NULL, // uses local computer
TEXT("WinApp")); // source name
应该返回一个有效的句柄值。MSDN的部分原文:
For example, WinApp is a valid source name if the registry has the following key:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\
EventLog\Application\WinApp但是我和几个朋友的机器上测试,结果却大不相同我的机器上的测试代码段
HANDLE h;
if ((h = RegisterEventSource(NULL,TEXT("SnortService"))) == NULL){
cout<<GetLastError()<<endl;
cout<<"not exist!"<<endl;
}
结果,无论我输入的子键值存在不存在,h均为NULL,
我的系统为中文2000 server+SP4七猫兄的测试代码段和我一样,但结果正常,如果子键存在,则h不为空,子键不存在,则h== hull,他的机器为中文2003 server猎狐兄的测试代码段如下
HANDLE h;
LPCTSTR s="134";
if ((h =RegisterEventSource(NULL,s)) == NULL){
AfxMessageBox("No Result");
}
测试结果更有意思:无论子键是否存在,h均不为空,和我的正好相反:-),猎狐兄的机器是日文2000
不知道这算不算微软的BUG,希望有条件的朋友也帮着测试一下,然后把结果和你的机器配置发上来,谢谢!
解决方案 »
- 获取指定路径的所有图片路径,错在哪里了!(两个帖子,+起来100分)
- 如何用C/C++打开某图片,计算图片大小,怎么计算 怎么打开,谢谢!!
- spy++ 能获得 不是激活窗口不显示的句柄吗?
- socket阻塞的问题。
- 我要找单位学习,实习.请前辈指教.
- 进度条的使用问题????
- 为什么我的程序release后执行和在vc开发工具中执行的结果不一样?
- 如何改变mdi窗口的风格
- 惨!!!惨!!!
- 如何获取本机的IP地址?
- 分享《Microsoft Windows Internals, 4ed》和《The Windows 2000 Device Driver Book》。
- 不知道为什么,我Bulid的时候,出现了以下提示,为什么?请高手......
用RegOpenKeyEx看返回值不也能知道键存在不存在吗?
用RegOpenKeyEx看返回值不也能知道键存在不存在吗?我的目的就是要测RegisterEventSource这个函数,呵呵。
看http://msdn.microsoft.com/library/en-us/eventlog/base/registereventsource.aspRegisterEventSourceThe RegisterEventSource function retrieves a registered handle to the specified event log人家说的是从event log里边找好不好
{
HANDLE h=NULL;
cout<< "result:" <<endl;
h = RegisterEventSource(NULL,TEXT("asasdf"));
cout<< "ErrorNum:" << GetLastError()<<endl;
cout<< "HANDLE ID:"<< h << endl;
if ( h == NULL)
{
cout<<"not exist!"<<endl;
}
}我的环境
简体中文Windows XP SP2至05月最新补丁
VISUAL C++ 2005 PROFESSIONAL键存在与不存在
都返回非NULL
result:
ErrorNum:0
HANDLE ID:00155DA0看了一下MSDN对这个函数的描述
在requirements里面
Client Requires Windows XP, Windows 2000 Professional, or Windows NT Workstation.
Server Requires Windows Server 2003, Windows 2000 Server, or Windows NT Server. 说明是支持windows xp的
但是却真的不生效,可能真的有问题
应该是还没有实现这个函数
这种情况在98下面挺多
如果系统不支持,很可能就直接实现了一个空函数
测试代码:
HANDLE h;
if ((h = RegisterEventSource(NULL,TEXT("SnortService"))) == NULL){
cout<<GetLastError()<<endl;
cout<<"not exist!"<<endl;
}结果,返回都为非NULL, 但是发现不关用什么关键字,返回的HANDLE值都一样。
而且,真正用这个HANDLE去写log的时候,都是失败的.
SDK只是提供用来开发的API
底层的还是kernel。dll那种东西。没法替换的。
具体的倒是真的可以问下ms
好像是有点奇怪
楼上的结果和我一样。
NTSTATUS
ElfRegisterEventSourceW (
IN PUNICODE_STRING UNCServerName,
IN PUNICODE_STRING ModuleName,
OUT PHANDLE LogHandle
)/*++Routine Description: This is the client DLL entry point for the ElfRegisterEventSource API. It creates an RPC binding for the server specified, and stores that
and additional data away. It returns a handle to the caller that can
be used to later on access the handle-specific information.Arguments: UNCServerName - Server with which to bind for subsequent operations. ModuleName - Supplies the name of the module to associate with
this handle. LogHandle - Location where log handle is to be returned.
Return Value: Returns an NTSTATUS code and, if no error, a handle that can be used
for subsequent Elf API calls.
--*/
{
NTSTATUS status = STATUS_SUCCESS;
UNICODE_STRING RegModuleName;
EVENTLOG_HANDLE_W ServerNameString; //
// Make sure input & output pointers are valid
// if (!LogHandle || !ModuleName || ModuleName->Length == 0) {
return(STATUS_INVALID_PARAMETER);
} if ((UNCServerName != NULL) && (UNCServerName->Length != 0)) {
ServerNameString = UNCServerName->Buffer;
} else {
ServerNameString = NULL;
} RtlInitUnicodeString( &RegModuleName, UNICODE_NULL); // Call service via RPC. Pass in major and minor version numbers. *LogHandle = NULL; // Must be NULL so RPC fills it in //
// Do the RPC call with an exception handler since RPC will raise an
// exception if anything fails. It is up to us to figure out what
// to do once the exception is raised.
//
RpcTryExcept { status = ElfrRegisterEventSourceW(
ServerNameString,
(PRPC_UNICODE_STRING)ModuleName,
(PRPC_UNICODE_STRING)&RegModuleName,
ELF_VERSION_MAJOR,
ELF_VERSION_MINOR,
(PIELF_HANDLE) LogHandle
); }
RpcExcept (1) { status = I_RpcMapWin32Status(RpcExceptionCode());
}
RpcEndExcept
return (status);
}
NTSTATUS
ElfpOpenELW (
IN EVENTLOG_HANDLE_W UNCServerName,
IN PRPC_UNICODE_STRING ModuleName,
IN PRPC_UNICODE_STRING RegModuleName,
IN ULONG MajorVersion,
IN ULONG MinorVersion,
OUT PIELF_HANDLE LogHandle,
IN ULONG DesiredAccess
)/*++Routine Description: Looks alot like ElfrOpenELW but also gets passed a DesiredAccess.Arguments: UNCServerName - Not used. ModuleName - Name of the module that is making this call. RegModuleName - Not used. MajorVersion/MinorVersion - The version of the client.
LogHandle - Pointer to the place where the pointer to the
context handle structure will be placed. DesiredAccess - Indicates the access desired for this logfile.Return Value: Returns an NTSTATUS code and, if no error, a "handle".
--*/
{
NTSTATUS Status;
PLOGMODULE Module;
IELF_HANDLE LogIHandle;
BOOL ForSecurityLog = FALSE; //
// Check arguments.
// Status = VerifyUnicodeString(ModuleName); if (!NT_SUCCESS(Status)) {
return(Status);
} if (LogHandle == NULL) {
return(STATUS_INVALID_PARAMETER);
} //
// Allocate a new structure for the context handle
// LogIHandle = (IELF_HANDLE) ElfpAllocateBuffer (
sizeof (*LogIHandle)
+ ModuleName->Length
+ sizeof (WCHAR)
); if (LogIHandle) { //
// Find the module structure in order to pull out the Atom.
//
// GetModuleStruc *always* succeeds! (returns default if module
// not found).
// Module = GetModuleStruc ((PUNICODE_STRING)ModuleName); //
// Validate the caller has appropriate access to this logfile.
// If this is the security log, then check privilege instead.
//
if (_wcsicmp(ELF_SECURITY_MODULE_NAME, Module->LogFile->LogModuleName->Buffer) == 0) {
ForSecurityLog = TRUE;
}
Status = ElfpAccessCheckAndAudit(
L"EventLog", // SubSystemName
L"LogFile", // ObjectTypeName
Module->ModuleName, // ObjectName
LogIHandle, // Context handle - required?
Module->LogFile->Sd, // Security Descriptor
DesiredAccess, // Requested Access
NULL, // GENERIC_MAPPING
ForSecurityLog // Indicates the check is for security log
); if (NT_SUCCESS(Status)) { LogIHandle->Atom = Module->ModuleAtom; LogIHandle->NameLength = ModuleName->Length + sizeof(WCHAR);
RtlMoveMemory( LogIHandle->Name,
ModuleName->Buffer,
ModuleName->Length
); LogIHandle->Name[ModuleName->Length / sizeof(WCHAR)] = L'\0'; LogIHandle->MajorVersion = MajorVersion; // Store the version
LogIHandle->MinorVersion = MinorVersion; // of the client //
// Initialize seek positions and flags to zero.
// LogIHandle->SeekRecordPos = 0;
LogIHandle->SeekBytePos = 0;
LogIHandle->Flags = 0;
LogIHandle->dwNotifyRequests = 0; //
// Link in this structure to the list of context handles
// LogIHandle->Signature = ELF_CONTEXTHANDLE_SIGN; // DEBUG
LinkContextHandle (LogIHandle); *LogHandle = LogIHandle; // Set return handle
Status = STATUS_SUCCESS; // Set return status
}
else {
ElfpFreeBuffer(LogIHandle);
} } else { Status = STATUS_NO_MEMORY;
} return (Status); UNREFERENCED_PARAMETER(UNCServerName);
UNREFERENCED_PARAMETER(RegModuleName);
}
NTSTATUS
ElfpAccessCheckAndAudit(
IN LPWSTR SubsystemName,
IN LPWSTR ObjectTypeName,
IN LPWSTR ObjectName,
IN OUT IELF_HANDLE ContextHandle,
IN PSECURITY_DESCRIPTOR SecurityDescriptor,
IN ACCESS_MASK DesiredAccess,
IN PGENERIC_MAPPING GenericMapping,
IN BOOL ForSecurityLog
)
/*++Routine Description: This function impersonates the caller so that it can perform access
validation using NtAccessCheckAndAuditAlarm; and reverts back to
itself before returning.Arguments: SubsystemName - Supplies a name string identifying the subsystem
calling this routine. ObjectTypeName - Supplies the name of the type of the object being
accessed. ObjectName - Supplies the name of the object being accessed. ContextHandle - Supplies the context handle to the object. On return, the
granted access is written to the AccessGranted field of this structure
if this call succeeds. SecurityDescriptor - A pointer to the Security Descriptor against which
acccess is to be checked. DesiredAccess - Supplies desired acccess mask. This mask must have been
previously mapped to contain no generic accesses. GenericMapping - Supplies a pointer to the generic mapping associated
with this object type. ForSecurityLog - TRUE if the access check is for the security log.
This is a special case that may require a privilege check.Return Value: NT status mapped to Win32 errors.--*/
{
NTSTATUS Status;
RPC_STATUS RpcStatus; UNICODE_STRING Subsystem;
UNICODE_STRING ObjectType;
UNICODE_STRING Object; BOOLEAN GenerateOnClose = FALSE;
NTSTATUS AccessStatus;
ACCESS_MASK GrantedAccess = 0;
HANDLE ClientToken = NULL;
PRIVILEGE_SET PrivilegeSet;
ULONG PrivilegeSetLength = sizeof(PRIVILEGE_SET);
ULONG privileges[1];
GenericMapping = &LogFileObjectMapping; RtlInitUnicodeString(&Subsystem, SubsystemName);
RtlInitUnicodeString(&ObjectType, ObjectTypeName);
RtlInitUnicodeString(&Object, ObjectName); if ((RpcStatus = RpcImpersonateClient(NULL)) != RPC_S_OK) { ElfDbgPrint(("[ELF] ElfpAccessCheckAndAudit: Failed to impersonate "
"client %08lx\n", RpcStatus)); return RpcStatus;
} //
// Get a token handle for the client
//
Status = NtOpenThreadToken (NtCurrentThread(),
TOKEN_QUERY, // DesiredAccess
TRUE, // OpenAsSelf
&ClientToken); if (!NT_SUCCESS(Status)) { ElfDbgPrint(("[ELF] ElfpAccessCheckAndAudit: NtOpenThreadToken Failed: "
"0x%lx\n",Status));
goto CleanExit;
} //
// We want to see if we can get the desired access, and if we do
// then we also want all our other accesses granted.
// MAXIMUM_ALLOWED gives us this.
//
DesiredAccess |= MAXIMUM_ALLOWED; //
// Bug #57153 -- Make sure that the current user has the right to manage
// the security log. Without this check, the Eventlog will allow all
// administrators to manage the log, even if they don't have the access
//
if (ForSecurityLog) {
DesiredAccess |= ACCESS_SYSTEM_SECURITY;
} Status = NtAccessCheck(SecurityDescriptor,
ClientToken,
DesiredAccess,
GenericMapping,
&PrivilegeSet,
&PrivilegeSetLength,
&GrantedAccess,
&AccessStatus); if (! NT_SUCCESS(Status)) { ElfDbgPrint(("[ELF] ElfpAccessCheckAndAudit: Error calling "
"NtAccessCheck %08lx\n",
Status)); goto CleanExit;
} if (AccessStatus != STATUS_SUCCESS) { ElfDbgPrint(("[ELF] ElfpAccessCheckAndAudit: Access status is %08lx\n",
AccessStatus)); //
// the ability to open the security log for purposes
// of backup.
// if ((AccessStatus == STATUS_ACCESS_DENIED) && (ForSecurityLog)) { //
// MarkBl 1/30/95 : First, evalutate the existing code (performed
// for read or clear access), since its
// privilege check is more rigorous than mine.
// Status = STATUS_ACCESS_DENIED; if (!(DesiredAccess & ELF_LOGFILE_WRITE)) { //
// If read or clear access to the security log is desired,
// then we will see if this user passes the privilege check.
//
//
// Do Privilege Check for SeSecurityPrivilege
// (SE_SECURITY_NAME).
//
// MarkBl 1/30/95 : Modified code to fall through on error
// instead of the jump to 'CleanExit'.
// Status = ElfpTestClientPrivilege(SE_SECURITY_PRIVILEGE,
ClientToken); if (NT_SUCCESS(Status)) { GrantedAccess |= (ELF_LOGFILE_READ |
ELF_LOGFILE_CLEAR);
}
else { ElfDbgPrint(("[ELF] ElfpAccessCheckAndAudit: "
"ElfpTestClientPrivilege failed %x\n",
Status));
}
} //
// MarkBl 1/30/95 : Finally, my code. If this user has backup
// privilege, let the open succeed.
// if (!NT_SUCCESS(Status)) { Status = ElfpTestClientPrivilege(SE_BACKUP_PRIVILEGE,
ClientToken); if (NT_SUCCESS(Status)) { GrantedAccess |= ELF_LOGFILE_BACKUP;
}
else {
goto CleanExit;
}
}
}
else {
Status = AccessStatus;
}
}
//
// Revert to Self
//
if ((RpcStatus = RpcRevertToSelf()) != RPC_S_OK) { ElfDbgPrint(("[ELF] ElfpAccessCheckAndAudit: Fail to revert to "
"self %08lx\n", RpcStatus));
//
// We don't return the error status here because we don't want
// to write over the other status that is being returned.
// } //
// Get SeAuditPrivilege so I can call NtOpenObjectAuditAlarm.
// If any of this stuff fails, I don't want the status to overwrite the
// status that I got back from the access and privilege checks.
// privileges[0] = SE_AUDIT_PRIVILEGE;
AccessStatus = ElfpGetPrivilege(1, privileges); if (!NT_SUCCESS(AccessStatus)) { ElfDbgPrint(("[ELF] ElfpAccessCheckAndAudit: ElfpGetPrivilege "
"(Enable) failed. Status is 0x%x\n",
AccessStatus));
} //
// Call the Audit Alarm function.
// AccessStatus = NtOpenObjectAuditAlarm (
&Subsystem,
(PVOID)ContextHandle,
&ObjectType,
&Object,
SecurityDescriptor,
ClientToken, // Handle ClientToken
DesiredAccess,
GrantedAccess,
&PrivilegeSet, // PPRIVLEGE_SET
FALSE, // BOOLEAN ObjectCreation,
TRUE, // BOOLEAN AccessGranted,
&GenerateOnClose); if (!NT_SUCCESS(AccessStatus)) {
ElfDbgPrint(("[ELF] ElfpAccessCheckAndAudit: NtOpenObjectAuditAlarm "
"failed. status is 0x%lx\n",
AccessStatus));
}
else { if (GenerateOnClose) {
ContextHandle->Flags |= ELF_LOG_HANDLE_GENERATE_ON_CLOSE;
}
} //
// Update the GrantedAccess in the context handle.
//
ContextHandle->GrantedAccess = GrantedAccess; NtClose(ClientToken); ElfpReleasePrivilege(); return(Status);CleanExit: //
// Revert to Self
//
if ((RpcStatus = RpcRevertToSelf()) != RPC_S_OK) { ElfDbgPrint(("[ELF] ElfpAccessCheckAndAudit: Fail to revert to "
"self %08lx\n",
RpcStatus));
//
// We don't return the error status here because we don't want
// to write over the other status that is being returned.
//
} if (ClientToken != NULL) {
NtClose(ClientToken);
} return(Status);
}
sevencat(七猫): Please do not post Microsoft source code.
谢谢,以后我会注意的。