Page 1 of 1

Problem with MSSCCI SccOpenProject Interface

Posted: Thu Feb 18, 2010 12:35 pm
by coderanger
I think you are implementing the SccOpenProject incorrectly in your "SourceGear Vault VS2003 Compatible Client" product/tool/interface.

According to the docs at http://msdn.microsoft.com/en-us/library/bb166506.aspx
lpAuxProjPath and lpProjName are read from the solution file, or they are returned from a call to the SccGetProjPath function. These parameters contain the strings that the source control plug-in associates with the project and are meaningful only to the plug-in. If no such strings are in the solution file and the user has not been prompted to browse (which would return a string through the SccGetProjPath function), the IDE passes empty strings for both lpAuxProjPath and lpProjName, and expects these values to be updated by the plug-in when this function returns
Basically if I call SccOpenProject with an empty value for lpAuxProjPath then it should return with the correct values, with regards to vault it would be something like "http://myvault/VaultService|MyProfile:2". Currently only SccGetProjPath returns a value for lpAuxProjPath which appears to be incorrect.

Re: Problem with MSSCCI SccOpenProject Interface

Posted: Thu Feb 18, 2010 4:03 pm
by lbauer
Thanks for the additional details. I have logged Work Item:15259, and we will take a closer look when we are working on the next release.

Re: Problem with MSSCCI SccOpenProject Interface

Posted: Thu Apr 08, 2010 1:55 pm
by triddle
I get a crash when I call SccOpenProject or SccGetProjPath. The crash happens at VaultIDE.dll!00006a0a(). The DLL is trying to access a NULL pointer.

According to the Microsoft documentation, all 4 of the string parameters can be empty strings.

Here is a simple test program that demonstrates the problem:

Code: Select all

// VaultTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h>
#include "scc.h"

typedef LONG (*SCC_GET_VERSION_PROC)(void);
SCC_GET_VERSION_PROC pSccGetVersion;

typedef SCCRTN (*SCC_INITIALIZE_PROC)( LPVOID* ppContext, HWND hWnd, LPCSTR lpCallerName, LPSTR lpSccName, LPLONG lpSccCaps, LPSTR lpAuxPathLabel, LPLONG pnCheckoutCommentLen, LPLONG pnCommentLen );
SCC_INITIALIZE_PROC pSccInitialize;

typedef SCCRTN (*SCC_UNINITIALIZE_PROC)( LPVOID pContext );
SCC_UNINITIALIZE_PROC pSccUninitialize;

typedef SCCRTN (*SCC_OPEN_PROJECT_PROC)( LPVOID pContext, HWND hWnd, LPSTR lpUser, LPSTR lpProjName, LPCSTR lpLocalProjPath, LPSTR lpAuxProjPath, LPCSTR lpComment, LPTEXTOUTPROC lpTextOutProc, LONG dwFlags );
SCC_OPEN_PROJECT_PROC pSccOpenProject;

typedef SCCRTN (*SCC_CLOSE_PROJECT_PROC)( LPVOID pContext );
SCC_CLOSE_PROJECT_PROC pSccCloseProject;

typedef SCCRTN (*SCC_GET_PROJ_PATH_PROC)( LPVOID pContext, HWND hWnd, LPSTR lpUser, LPSTR lpProjName, LPSTR lpLocalPath, LPSTR lpAuxProjPath, BOOL bAllowChangePath, LPBOOL pbNew );
SCC_GET_PROJ_PATH_PROC pSccGetProjPath;

typedef SCCRTN (*SCC_QUERY_INFO_PROC)( LPVOID pContext,  LONG nFiles, LPCSTR* lpFileNames, LPLONG lpStatus );
SCC_QUERY_INFO_PROC pSccQueryInfo;

int _tmain(int argc, _TCHAR* argv[])
{
	DWORD dwSize = _MAX_PATH;
	TCHAR szProviderRegKey[ _MAX_PATH ];
	LPVOID pContext;

	if ( RegGetValue( HKEY_LOCAL_MACHINE, STR_SCC_PROVIDER_REG_LOCATION, STR_PROVIDERREGKEY, RRF_RT_REG_SZ, NULL, szProviderRegKey, &dwSize ) != ERROR_SUCCESS )
	{
		return 0;
	}

	dwSize = _MAX_PATH;
	TCHAR szProviderFilePath[ _MAX_PATH ];

	if ( RegGetValue( HKEY_LOCAL_MACHINE, szProviderRegKey, STR_SCCPROVIDERPATH, RRF_RT_REG_SZ, NULL, szProviderFilePath, &dwSize ) != ERROR_SUCCESS )
	{
		return 0;
	}

	HMODULE hSCCLib = LoadLibrary( szProviderFilePath );

	if ( hSCCLib == NULL )
	{
		return 0;
	}

	pSccGetVersion = (SCC_GET_VERSION_PROC)GetProcAddress( hSCCLib, "SccGetVersion" );

	if ( pSccGetVersion == NULL )
	{
		return 0;
	}

	if ( pSccGetVersion() != SCC_VER_NUM )
	{
		return 0;
	}

	pSccInitialize = (SCC_INITIALIZE_PROC)GetProcAddress( hSCCLib, "SccInitialize" );

	if ( pSccInitialize == NULL )
	{
		return 0;
	}

	char szSCCName[ SCC_NAME_SIZE ];
	char szAuthPathLabel[ SCC_AUXLABEL_SIZE ];
	long lCaps = 0;
	long nCheckoutCommentLen = 0;
	long nCommentLen = 0;

	if ( pSccInitialize( &pContext, NULL, "Source Code Control Test", szSCCName, &lCaps, szAuthPathLabel, &nCheckoutCommentLen, &nCommentLen ) != SCC_OK )
	{
		return 0;
	}

	pSccGetProjPath = (SCC_GET_PROJ_PATH_PROC)GetProcAddress( hSCCLib, "SccGetProjPath" );

	if ( pSccGetProjPath == NULL )
	{
		return 0;
	}

	char szUser[ SCC_USER_SIZE ];
	char szProjectName[ SCC_PRJPATH_SIZE ];
	char szProjectLocalPath[ SCC_PRJPATH_SIZE ];
	char szAuxProjectPath[ SCC_PRJPATH_SIZE ];
	BOOL bNew = FALSE;

	szUser[0] = 0;
	szProjectName[0] = 0;
	szProjectLocalPath[0] = 0;
	szAuxProjectPath[0] = 0;

	//////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// Crash happens here!
	//////////////////////////////////////////////////////////////////////////////////////////////////////////////
	SCCRTN rvGet = pSccGetProjPath( pContext, NULL, szUser, szProjectName, szProjectLocalPath, szAuxProjectPath, TRUE, &bNew );

	pSccUninitialize = (SCC_UNINITIALIZE_PROC)GetProcAddress( hSCCLib, "SccUninitialize" );

	if ( pSccUninitialize )
	{
		pSccUninitialize( pContext );
	}

	FreeLibrary( hSCCLib );

	return 0;
}