Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

277 lines
7.0 KiB

#include "uddi.xp.h"
//
// Add your new Extended Stored Procedure from a Visual Studio Data Project,
// or using the SQL Server Enterprise Manager, or by executing the following
// SQL command:
// sp_addextendedproc 'xp_recalculate_statistics', 'uddi.xp.dll'
//
// You may drop the extended stored procedure by using the SQL command:
// sp_dropextendedproc 'xp_recalculate_statistics'
//
// You may release the DLL from the Server (to delete or replace the file), by
// using the SQL command:
// DBCC xp_recalculate_statistics(FREE)
//
// sp_addextendedproc 'xp_recalculate_statistics', 'uddi.xp.dll'
// sp_dropextendedproc 'xp_recalculate_statistics'
// exec xp_recalculate_statistics
//
// DBCC xp_recalculate_statistics(FREE)
//
RETCODE xp_recalculate_statistics( SRV_PROC *srvproc )
{
DBSMALLINT i = 0;
DBCHAR spName[MAXNAME];
DBCHAR spText[MAXTEXT];
DWORD cbReadBuffer = 0;
DBINT cnt = 0;
BOOL fSuccess = FALSE;
STARTUPINFOA si;
PROCESS_INFORMATION pi;
#if defined( _DEBUG ) || defined( DBG )
CHAR bReadBuffer[255];
SECURITY_ATTRIBUTES saPipe;
HANDLE hReadPipe = NULL;
HANDLE hWritePipe = NULL;
DWORD dwExitCode = 0;
BOOL fSendRowNotFailed = TRUE;
#endif
//
// Name of this procedure
//
_snprintf( spName, MAXNAME, "xp_recalculate_statistics" );
spName[ MAXNAME - 1 ] = 0x00;
//
// Send a text message
//
_snprintf( spText, MAXTEXT, "UDDI Services Extended Stored Procedure: %s\n", spName );
spText[ MAXTEXT - 1 ] = 0x00;
srv_sendmsg(
srvproc,
SRV_MSG_INFO,
0,
(DBTINYINT)0,
(DBTINYINT)0,
NULL,
0,
0,
spText,
SRV_NULLTERM );
string strRecalcStatsFile = GetUddiInstallDirectory();
if( 0 == strRecalcStatsFile.length() )
{
ReportError( srvproc, "GetUddiInstallDirectory" );
return FAIL;
}
strRecalcStatsFile += "\\recalcstats.exe";
_snprintf( spText, MAXTEXT, "Recalcstats.exe Installed at location: %s\n", strRecalcStatsFile.c_str() );
spText[ MAXTEXT - 1 ] = 0x00;
srv_sendmsg(
srvproc,
SRV_MSG_INFO,
0,
(DBTINYINT)0,
(DBTINYINT)0,
NULL,
0,
0,
spText,
SRV_NULLTERM );
#if defined( _DEBUG ) || defined( DBG )
//
// Create child process to execute the command string. Use an
// anonymous pipe to read the output from the command and send
// any results to the client.
// In order for the child process to be able to write
// to the anonymous pipe, the handle must be marked as
// inheritable by child processes by setting the
// SECURITY_ATTRIBUTES.bInheritHandle flag to TRUE.
//
saPipe.nLength = sizeof( SECURITY_ATTRIBUTES );
saPipe.lpSecurityDescriptor = NULL;
saPipe.bInheritHandle = TRUE;
fSuccess = CreatePipe(
&hReadPipe, // read handle
&hWritePipe, // write handle
&saPipe, // security descriptor
0 ); // use default pipe buffer size
if( !fSuccess )
{
ReportError( srvproc, "CreatePipe", GetLastError() );
return FAIL;
}
#endif //DBG || _DEBUG
//
// Now we must set standard out and standard error to the
// write end of the pipe. Once standard out and standard
// error are set to the pipe handle, we must close the pipe
// handle so that when the child process dies, the write end
// of the pipe will close, setting an EOF condition on the pipe.
//
memset( &si, 0, sizeof(si) );
si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
si.wShowWindow = SW_HIDE;
#if defined( _DEBUG ) || defined( DBG )
si.hStdOutput = hWritePipe;
si.hStdError = hWritePipe;
#endif // DBG || _DEBUG
//
// Set the fInheritHandles parameter to TRUE so that open
// file handles will be inheritied. We can close the child
// process and thread handles as we won't be needing them.
// The child process will not die until these handles are
// closed.
//
fSuccess = CreateProcessA(
strRecalcStatsFile.c_str(), // filename
NULL, // command line for child
NULL, // process security descriptor
NULL, // thread security descriptor
TRUE, // inherit handles?
0, // creation flags
NULL, // inherited environment address
NULL, // startup dir; NULL = start in current
&si, // pointer to startup info (input)
&pi ); // pointer to process info (output)
if( !fSuccess )
{
ReportError( srvproc, "CreateProcess", GetLastError() );
return FAIL;
}
#if defined( _DEBUG ) || defined( DBG )
//
// We need to close our instance of the inherited pipe write
// handle now that it's been inherited so that it will actually
// close when the child process ends. This will put an EOF
// condition on the pipe which we can then detect.
//
fSuccess = CloseHandle( hWritePipe );
if( !fSuccess )
{
ReportError( srvproc, "CloseHandle", GetLastError() );
CloseHandle( pi.hThread );
CloseHandle( pi.hProcess );
return FAIL;
}
//
// Now read from the pipe until EOF condition reached.
//
do
{
cnt = 0;
while( ( cnt < ( sizeof( bReadBuffer ) / sizeof( bReadBuffer[0] ) ) ) &&
( 0 != (fSuccess = ReadFile(
hReadPipe, // read handle
&bReadBuffer[cnt], // buffer for incoming data
1, // number of bytes to read
&cbReadBuffer, // number of bytes actually read
NULL ) ) ) )
{
if( !fSuccess )
{
if( ERROR_BROKEN_PIPE == GetLastError() )
{
break;
}
//
// Child has died
//
ReportError( srvproc, "CloseHandle", GetLastError() );
CloseHandle( pi.hThread );
CloseHandle( pi.hProcess );
return FAIL;
}
if( '\n' == bReadBuffer[ cnt ] )
{
break;
}
else
{
cnt++;
}
}
if( fSuccess && cbReadBuffer )
{
if( !cnt )
{
bReadBuffer[ 0 ] = ' ';
cnt = 1;
}
//
// Remove carriage return if it exists
//
if( 0x0D == bReadBuffer[ cnt-1 ] )
{
cnt--;
}
if( cnt >= 0 )
{
bReadBuffer[ cnt ] = 0;
//
// Send program output back as information
//
srv_sendmsg(
srvproc,
SRV_MSG_INFO,
0,
(DBTINYINT)0,
(DBTINYINT)0,
NULL,
0,
0,
bReadBuffer,
cnt );
}
}
}
while( fSuccess && cbReadBuffer );
//
// Close the trace file, pipe handles
//
CloseHandle( hReadPipe );
if( !GetExitCodeProcess( pi.hProcess, &dwExitCode ) || dwExitCode != 0 )
{
ReportError( srvproc, "GetExitCodeProcess", dwExitCode );
return FAIL;
}
#endif // DBG || _DEBUG
CloseHandle( pi.hThread );
CloseHandle( pi.hProcess );
return XP_NOERROR ;
}