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
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 ;
|
|
}
|