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.

276 lines
7.0 KiB

  1. #include "uddi.xp.h"
  2. //
  3. // Add your new Extended Stored Procedure from a Visual Studio Data Project,
  4. // or using the SQL Server Enterprise Manager, or by executing the following
  5. // SQL command:
  6. // sp_addextendedproc 'xp_recalculate_statistics', 'uddi.xp.dll'
  7. //
  8. // You may drop the extended stored procedure by using the SQL command:
  9. // sp_dropextendedproc 'xp_recalculate_statistics'
  10. //
  11. // You may release the DLL from the Server (to delete or replace the file), by
  12. // using the SQL command:
  13. // DBCC xp_recalculate_statistics(FREE)
  14. //
  15. // sp_addextendedproc 'xp_recalculate_statistics', 'uddi.xp.dll'
  16. // sp_dropextendedproc 'xp_recalculate_statistics'
  17. // exec xp_recalculate_statistics
  18. //
  19. // DBCC xp_recalculate_statistics(FREE)
  20. //
  21. RETCODE xp_recalculate_statistics( SRV_PROC *srvproc )
  22. {
  23. DBSMALLINT i = 0;
  24. DBCHAR spName[MAXNAME];
  25. DBCHAR spText[MAXTEXT];
  26. DWORD cbReadBuffer = 0;
  27. DBINT cnt = 0;
  28. BOOL fSuccess = FALSE;
  29. STARTUPINFOA si;
  30. PROCESS_INFORMATION pi;
  31. #if defined( _DEBUG ) || defined( DBG )
  32. CHAR bReadBuffer[255];
  33. SECURITY_ATTRIBUTES saPipe;
  34. HANDLE hReadPipe = NULL;
  35. HANDLE hWritePipe = NULL;
  36. DWORD dwExitCode = 0;
  37. BOOL fSendRowNotFailed = TRUE;
  38. #endif
  39. //
  40. // Name of this procedure
  41. //
  42. _snprintf( spName, MAXNAME, "xp_recalculate_statistics" );
  43. spName[ MAXNAME - 1 ] = 0x00;
  44. //
  45. // Send a text message
  46. //
  47. _snprintf( spText, MAXTEXT, "UDDI Services Extended Stored Procedure: %s\n", spName );
  48. spText[ MAXTEXT - 1 ] = 0x00;
  49. srv_sendmsg(
  50. srvproc,
  51. SRV_MSG_INFO,
  52. 0,
  53. (DBTINYINT)0,
  54. (DBTINYINT)0,
  55. NULL,
  56. 0,
  57. 0,
  58. spText,
  59. SRV_NULLTERM );
  60. string strRecalcStatsFile = GetUddiInstallDirectory();
  61. if( 0 == strRecalcStatsFile.length() )
  62. {
  63. ReportError( srvproc, "GetUddiInstallDirectory" );
  64. return FAIL;
  65. }
  66. strRecalcStatsFile += "\\recalcstats.exe";
  67. _snprintf( spText, MAXTEXT, "Recalcstats.exe Installed at location: %s\n", strRecalcStatsFile.c_str() );
  68. spText[ MAXTEXT - 1 ] = 0x00;
  69. srv_sendmsg(
  70. srvproc,
  71. SRV_MSG_INFO,
  72. 0,
  73. (DBTINYINT)0,
  74. (DBTINYINT)0,
  75. NULL,
  76. 0,
  77. 0,
  78. spText,
  79. SRV_NULLTERM );
  80. #if defined( _DEBUG ) || defined( DBG )
  81. //
  82. // Create child process to execute the command string. Use an
  83. // anonymous pipe to read the output from the command and send
  84. // any results to the client.
  85. // In order for the child process to be able to write
  86. // to the anonymous pipe, the handle must be marked as
  87. // inheritable by child processes by setting the
  88. // SECURITY_ATTRIBUTES.bInheritHandle flag to TRUE.
  89. //
  90. saPipe.nLength = sizeof( SECURITY_ATTRIBUTES );
  91. saPipe.lpSecurityDescriptor = NULL;
  92. saPipe.bInheritHandle = TRUE;
  93. fSuccess = CreatePipe(
  94. &hReadPipe, // read handle
  95. &hWritePipe, // write handle
  96. &saPipe, // security descriptor
  97. 0 ); // use default pipe buffer size
  98. if( !fSuccess )
  99. {
  100. ReportError( srvproc, "CreatePipe", GetLastError() );
  101. return FAIL;
  102. }
  103. #endif //DBG || _DEBUG
  104. //
  105. // Now we must set standard out and standard error to the
  106. // write end of the pipe. Once standard out and standard
  107. // error are set to the pipe handle, we must close the pipe
  108. // handle so that when the child process dies, the write end
  109. // of the pipe will close, setting an EOF condition on the pipe.
  110. //
  111. memset( &si, 0, sizeof(si) );
  112. si.cb = sizeof(si);
  113. si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
  114. si.wShowWindow = SW_HIDE;
  115. #if defined( _DEBUG ) || defined( DBG )
  116. si.hStdOutput = hWritePipe;
  117. si.hStdError = hWritePipe;
  118. #endif // DBG || _DEBUG
  119. //
  120. // Set the fInheritHandles parameter to TRUE so that open
  121. // file handles will be inheritied. We can close the child
  122. // process and thread handles as we won't be needing them.
  123. // The child process will not die until these handles are
  124. // closed.
  125. //
  126. fSuccess = CreateProcessA(
  127. strRecalcStatsFile.c_str(), // filename
  128. NULL, // command line for child
  129. NULL, // process security descriptor
  130. NULL, // thread security descriptor
  131. TRUE, // inherit handles?
  132. 0, // creation flags
  133. NULL, // inherited environment address
  134. NULL, // startup dir; NULL = start in current
  135. &si, // pointer to startup info (input)
  136. &pi ); // pointer to process info (output)
  137. if( !fSuccess )
  138. {
  139. ReportError( srvproc, "CreateProcess", GetLastError() );
  140. return FAIL;
  141. }
  142. #if defined( _DEBUG ) || defined( DBG )
  143. //
  144. // We need to close our instance of the inherited pipe write
  145. // handle now that it's been inherited so that it will actually
  146. // close when the child process ends. This will put an EOF
  147. // condition on the pipe which we can then detect.
  148. //
  149. fSuccess = CloseHandle( hWritePipe );
  150. if( !fSuccess )
  151. {
  152. ReportError( srvproc, "CloseHandle", GetLastError() );
  153. CloseHandle( pi.hThread );
  154. CloseHandle( pi.hProcess );
  155. return FAIL;
  156. }
  157. //
  158. // Now read from the pipe until EOF condition reached.
  159. //
  160. do
  161. {
  162. cnt = 0;
  163. while( ( cnt < ( sizeof( bReadBuffer ) / sizeof( bReadBuffer[0] ) ) ) &&
  164. ( 0 != (fSuccess = ReadFile(
  165. hReadPipe, // read handle
  166. &bReadBuffer[cnt], // buffer for incoming data
  167. 1, // number of bytes to read
  168. &cbReadBuffer, // number of bytes actually read
  169. NULL ) ) ) )
  170. {
  171. if( !fSuccess )
  172. {
  173. if( ERROR_BROKEN_PIPE == GetLastError() )
  174. {
  175. break;
  176. }
  177. //
  178. // Child has died
  179. //
  180. ReportError( srvproc, "CloseHandle", GetLastError() );
  181. CloseHandle( pi.hThread );
  182. CloseHandle( pi.hProcess );
  183. return FAIL;
  184. }
  185. if( '\n' == bReadBuffer[ cnt ] )
  186. {
  187. break;
  188. }
  189. else
  190. {
  191. cnt++;
  192. }
  193. }
  194. if( fSuccess && cbReadBuffer )
  195. {
  196. if( !cnt )
  197. {
  198. bReadBuffer[ 0 ] = ' ';
  199. cnt = 1;
  200. }
  201. //
  202. // Remove carriage return if it exists
  203. //
  204. if( 0x0D == bReadBuffer[ cnt-1 ] )
  205. {
  206. cnt--;
  207. }
  208. if( cnt >= 0 )
  209. {
  210. bReadBuffer[ cnt ] = 0;
  211. //
  212. // Send program output back as information
  213. //
  214. srv_sendmsg(
  215. srvproc,
  216. SRV_MSG_INFO,
  217. 0,
  218. (DBTINYINT)0,
  219. (DBTINYINT)0,
  220. NULL,
  221. 0,
  222. 0,
  223. bReadBuffer,
  224. cnt );
  225. }
  226. }
  227. }
  228. while( fSuccess && cbReadBuffer );
  229. //
  230. // Close the trace file, pipe handles
  231. //
  232. CloseHandle( hReadPipe );
  233. if( !GetExitCodeProcess( pi.hProcess, &dwExitCode ) || dwExitCode != 0 )
  234. {
  235. ReportError( srvproc, "GetExitCodeProcess", dwExitCode );
  236. return FAIL;
  237. }
  238. #endif // DBG || _DEBUG
  239. CloseHandle( pi.hThread );
  240. CloseHandle( pi.hProcess );
  241. return XP_NOERROR ;
  242. }