- build a standard Wine list of appids instead of using an array
- use appid pointers instead of array indexes
This commit is contained in:
parent
92ba28851a
commit
febad089ce
|
@ -114,7 +114,19 @@ typedef struct tagMSIFILE
|
||||||
LPWSTR SourcePath;
|
LPWSTR SourcePath;
|
||||||
LPWSTR TargetPath;
|
LPWSTR TargetPath;
|
||||||
BOOL Temporary;
|
BOOL Temporary;
|
||||||
}MSIFILE;
|
} MSIFILE;
|
||||||
|
|
||||||
|
typedef struct tagMSIAPPID
|
||||||
|
{
|
||||||
|
struct list entry;
|
||||||
|
WCHAR AppID[IDENTIFIER_SIZE]; /* Primary key */
|
||||||
|
LPWSTR RemoteServerName;
|
||||||
|
LPWSTR LocalServer;
|
||||||
|
LPWSTR ServiceParameters;
|
||||||
|
LPWSTR DllSurrogate;
|
||||||
|
BOOL ActivateAtStorage;
|
||||||
|
BOOL RunAsInteractiveUser;
|
||||||
|
} MSIAPPID;
|
||||||
|
|
||||||
typedef struct tagMSICLASS
|
typedef struct tagMSICLASS
|
||||||
{
|
{
|
||||||
|
@ -124,7 +136,7 @@ typedef struct tagMSICLASS
|
||||||
INT ProgIDIndex;
|
INT ProgIDIndex;
|
||||||
LPWSTR ProgIDText;
|
LPWSTR ProgIDText;
|
||||||
LPWSTR Description;
|
LPWSTR Description;
|
||||||
INT AppIDIndex;
|
MSIAPPID *AppID;
|
||||||
LPWSTR FileTypeMask;
|
LPWSTR FileTypeMask;
|
||||||
LPWSTR IconPath;
|
LPWSTR IconPath;
|
||||||
LPWSTR DefInprocHandler;
|
LPWSTR DefInprocHandler;
|
||||||
|
@ -182,17 +194,6 @@ typedef struct tagMSIMIME
|
||||||
BOOL InstallMe;
|
BOOL InstallMe;
|
||||||
} MSIMIME;
|
} MSIMIME;
|
||||||
|
|
||||||
typedef struct tagMSIAPPID
|
|
||||||
{
|
|
||||||
WCHAR AppID[IDENTIFIER_SIZE]; /* Primary key */
|
|
||||||
LPWSTR RemoteServerName;
|
|
||||||
LPWSTR LocalServer;
|
|
||||||
LPWSTR ServiceParameters;
|
|
||||||
LPWSTR DllSurrogate;
|
|
||||||
BOOL ActivateAtStorage;
|
|
||||||
BOOL RunAsInteractiveUser;
|
|
||||||
} MSIAPPID;
|
|
||||||
|
|
||||||
enum SCRIPTS {
|
enum SCRIPTS {
|
||||||
INSTALL_SCRIPT = 0,
|
INSTALL_SCRIPT = 0,
|
||||||
COMMIT_SCRIPT = 1,
|
COMMIT_SCRIPT = 1,
|
||||||
|
|
|
@ -54,69 +54,67 @@ extern const WCHAR szUnregisterExtensionInfo[];
|
||||||
extern const WCHAR szUnregisterMIMEInfo[];
|
extern const WCHAR szUnregisterMIMEInfo[];
|
||||||
extern const WCHAR szUnregisterProgIdInfo[];
|
extern const WCHAR szUnregisterProgIdInfo[];
|
||||||
|
|
||||||
static INT load_appid(MSIPACKAGE* package, MSIRECORD *row)
|
static MSIAPPID *load_appid( MSIPACKAGE* package, MSIRECORD *row )
|
||||||
{
|
{
|
||||||
DWORD index = package->loaded_appids;
|
|
||||||
DWORD sz;
|
DWORD sz;
|
||||||
LPCWSTR buffer;
|
LPCWSTR buffer;
|
||||||
|
MSIAPPID *appid;
|
||||||
|
|
||||||
/* fill in the data */
|
/* fill in the data */
|
||||||
|
|
||||||
package->loaded_appids++;
|
appid = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MSIAPPID) );
|
||||||
if (package->loaded_appids == 1)
|
if (!appid)
|
||||||
package->appids = HeapAlloc(GetProcessHeap(),0,sizeof(MSIAPPID));
|
return NULL;
|
||||||
else
|
|
||||||
package->appids = HeapReAlloc(GetProcessHeap(),0,
|
|
||||||
package->appids, package->loaded_appids * sizeof(MSIAPPID));
|
|
||||||
|
|
||||||
memset(&package->appids[index],0,sizeof(MSIAPPID));
|
|
||||||
|
|
||||||
sz = IDENTIFIER_SIZE;
|
sz = IDENTIFIER_SIZE;
|
||||||
MSI_RecordGetStringW(row, 1, package->appids[index].AppID, &sz);
|
MSI_RecordGetStringW(row, 1, appid->AppID, &sz);
|
||||||
TRACE("loading appid %s\n",debugstr_w(package->appids[index].AppID));
|
TRACE("loading appid %s\n", debugstr_w( appid->AppID ));
|
||||||
|
|
||||||
buffer = MSI_RecordGetString(row,2);
|
buffer = MSI_RecordGetString(row,2);
|
||||||
deformat_string(package,buffer,&package->appids[index].RemoteServerName);
|
deformat_string( package, buffer, &appid->RemoteServerName );
|
||||||
|
|
||||||
package->appids[index].LocalServer = load_dynamic_stringW(row,3);
|
appid->LocalServer = load_dynamic_stringW(row,3);
|
||||||
package->appids[index].ServiceParameters = load_dynamic_stringW(row,4);
|
appid->ServiceParameters = load_dynamic_stringW(row,4);
|
||||||
package->appids[index].DllSurrogate = load_dynamic_stringW(row,5);
|
appid->DllSurrogate = load_dynamic_stringW(row,5);
|
||||||
|
|
||||||
package->appids[index].ActivateAtStorage = !MSI_RecordIsNull(row,6);
|
appid->ActivateAtStorage = !MSI_RecordIsNull(row,6);
|
||||||
package->appids[index].RunAsInteractiveUser = !MSI_RecordIsNull(row,7);
|
appid->RunAsInteractiveUser = !MSI_RecordIsNull(row,7);
|
||||||
|
|
||||||
|
list_add_tail( &package->appids, &appid->entry );
|
||||||
|
|
||||||
return index;
|
return appid;
|
||||||
}
|
}
|
||||||
|
|
||||||
static INT load_given_appid(MSIPACKAGE *package, LPCWSTR appid)
|
static MSIAPPID *load_given_appid( MSIPACKAGE *package, LPCWSTR name )
|
||||||
{
|
{
|
||||||
INT rc;
|
|
||||||
MSIRECORD *row;
|
MSIRECORD *row;
|
||||||
INT i;
|
MSIAPPID *appid;
|
||||||
static const WCHAR ExecSeqQuery[] =
|
static const WCHAR ExecSeqQuery[] =
|
||||||
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
|
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
|
||||||
'`','A','p','p','I','d','`',' ','W','H','E','R','E',' ',
|
'`','A','p','p','I','d','`',' ','W','H','E','R','E',' ',
|
||||||
'`','A','p','p','I','d','`',' ','=',' ','\'','%','s','\'',0};
|
'`','A','p','p','I','d','`',' ','=',' ','\'','%','s','\'',0};
|
||||||
|
|
||||||
if (!appid)
|
if (!name)
|
||||||
return -1;
|
return NULL;
|
||||||
|
|
||||||
/* check for appids already loaded */
|
/* check for appids already loaded */
|
||||||
for (i = 0; i < package->loaded_appids; i++)
|
LIST_FOR_EACH_ENTRY( appid, &package->appids, MSIAPPID, entry )
|
||||||
if (strcmpiW(package->appids[i].AppID,appid)==0)
|
{
|
||||||
|
if (lstrcmpiW( appid->AppID, name )==0)
|
||||||
{
|
{
|
||||||
TRACE("found appid %s at index %i\n",debugstr_w(appid),i);
|
TRACE("found appid %s %p\n", debugstr_w(name), appid);
|
||||||
return i;
|
return appid;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
row = MSI_QueryGetRecord(package->db, ExecSeqQuery, appid);
|
row = MSI_QueryGetRecord(package->db, ExecSeqQuery, appid);
|
||||||
if (!row)
|
if (!row)
|
||||||
return -1;
|
return NULL;
|
||||||
|
|
||||||
rc = load_appid(package, row);
|
appid = load_appid(package, row);
|
||||||
msiobj_release(&row->hdr);
|
msiobj_release(&row->hdr);
|
||||||
|
|
||||||
return rc;
|
return appid;
|
||||||
}
|
}
|
||||||
|
|
||||||
static INT load_given_progid(MSIPACKAGE *package, LPCWSTR progid);
|
static INT load_given_progid(MSIPACKAGE *package, LPCWSTR progid);
|
||||||
|
@ -263,10 +261,7 @@ static INT load_class(MSIPACKAGE* package, MSIRECORD *row)
|
||||||
|
|
||||||
buffer = MSI_RecordGetString(row,6);
|
buffer = MSI_RecordGetString(row,6);
|
||||||
if (buffer)
|
if (buffer)
|
||||||
package->classes[index].AppIDIndex =
|
package->classes[index].AppID = load_given_appid(package, buffer);
|
||||||
load_given_appid(package, buffer);
|
|
||||||
else
|
|
||||||
package->classes[index].AppIDIndex = -1;
|
|
||||||
|
|
||||||
package->classes[index].FileTypeMask = load_dynamic_stringW(row,7);
|
package->classes[index].FileTypeMask = load_dynamic_stringW(row,7);
|
||||||
|
|
||||||
|
@ -793,88 +788,80 @@ static void mark_mime_for_install(MSIPACKAGE* package, INT index)
|
||||||
mime->InstallMe = TRUE;
|
mime->InstallMe = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static UINT register_appid(MSIPACKAGE *package, int appidIndex, LPCWSTR app )
|
static UINT register_appid(MSIAPPID *appid, LPCWSTR app )
|
||||||
{
|
{
|
||||||
static const WCHAR szAppID[] = { 'A','p','p','I','D',0 };
|
static const WCHAR szAppID[] = { 'A','p','p','I','D',0 };
|
||||||
HKEY hkey2,hkey3;
|
HKEY hkey2,hkey3;
|
||||||
|
UINT size;
|
||||||
if (!package)
|
|
||||||
return ERROR_INVALID_HANDLE;
|
|
||||||
|
|
||||||
RegCreateKeyW(HKEY_CLASSES_ROOT,szAppID,&hkey2);
|
RegCreateKeyW(HKEY_CLASSES_ROOT,szAppID,&hkey2);
|
||||||
RegCreateKeyW(hkey2,package->appids[appidIndex].AppID,&hkey3);
|
RegCreateKeyW( hkey2, appid->AppID, &hkey3 );
|
||||||
RegSetValueExW(hkey3,NULL,0,REG_SZ,(LPVOID)app,
|
RegSetValueExW( hkey3, NULL, 0, REG_SZ,
|
||||||
(strlenW(app)+1)*sizeof(WCHAR));
|
(LPBYTE)app, (strlenW(app)+1)*sizeof(WCHAR) );
|
||||||
|
|
||||||
if (package->appids[appidIndex].RemoteServerName)
|
if (appid->RemoteServerName)
|
||||||
{
|
{
|
||||||
UINT size;
|
|
||||||
static const WCHAR szRemoteServerName[] =
|
static const WCHAR szRemoteServerName[] =
|
||||||
{'R','e','m','o','t','e','S','e','r','v','e','r','N','a','m','e',
|
{'R','e','m','o','t','e','S','e','r','v','e','r','N','a','m','e',0};
|
||||||
0};
|
|
||||||
|
|
||||||
size = (strlenW(package->appids[appidIndex].RemoteServerName)+1) *
|
size = (lstrlenW(appid->RemoteServerName)+1) * sizeof(WCHAR);
|
||||||
sizeof(WCHAR);
|
|
||||||
|
|
||||||
RegSetValueExW(hkey3,szRemoteServerName,0,REG_SZ,
|
RegSetValueExW( hkey3, szRemoteServerName, 0, REG_SZ,
|
||||||
(LPVOID)package->appids[appidIndex].RemoteServerName,
|
(LPBYTE)appid->RemoteServerName, size);
|
||||||
size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (package->appids[appidIndex].LocalServer)
|
if (appid->LocalServer)
|
||||||
{
|
{
|
||||||
static const WCHAR szLocalService[] =
|
static const WCHAR szLocalService[] =
|
||||||
{'L','o','c','a','l','S','e','r','v','i','c','e',0};
|
{'L','o','c','a','l','S','e','r','v','i','c','e',0};
|
||||||
UINT size;
|
|
||||||
size = (strlenW(package->appids[appidIndex].LocalServer)+1) *
|
|
||||||
sizeof(WCHAR);
|
|
||||||
|
|
||||||
RegSetValueExW(hkey3,szLocalService,0,REG_SZ,
|
size = (lstrlenW(appid->LocalServer)+1) * sizeof(WCHAR);
|
||||||
(LPVOID)package->appids[appidIndex].LocalServer,size);
|
|
||||||
|
RegSetValueExW( hkey3, szLocalService, 0, REG_SZ,
|
||||||
|
(LPBYTE)appid->LocalServer, size );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (package->appids[appidIndex].ServiceParameters)
|
if (appid->ServiceParameters)
|
||||||
{
|
{
|
||||||
static const WCHAR szService[] =
|
static const WCHAR szService[] =
|
||||||
{'S','e','r','v','i','c','e',
|
{'S','e','r','v','i','c','e',
|
||||||
'P','a','r','a','m','e','t','e','r','s',0};
|
'P','a','r','a','m','e','t','e','r','s',0};
|
||||||
UINT size;
|
|
||||||
size = (strlenW(package->appids[appidIndex].ServiceParameters)+1) *
|
size = (lstrlenW(appid->ServiceParameters)+1) * sizeof(WCHAR);
|
||||||
sizeof(WCHAR);
|
RegSetValueExW( hkey3, szService, 0, REG_SZ,
|
||||||
RegSetValueExW(hkey3,szService,0,REG_SZ,
|
(LPBYTE)appid->ServiceParameters, size );
|
||||||
(LPVOID)package->appids[appidIndex].ServiceParameters,
|
|
||||||
size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (package->appids[appidIndex].DllSurrogate)
|
if (appid->DllSurrogate)
|
||||||
{
|
{
|
||||||
static const WCHAR szDLL[] =
|
static const WCHAR szDLL[] =
|
||||||
{'D','l','l','S','u','r','r','o','g','a','t','e',0};
|
{'D','l','l','S','u','r','r','o','g','a','t','e',0};
|
||||||
UINT size;
|
|
||||||
size = (strlenW(package->appids[appidIndex].DllSurrogate)+1) *
|
size = (lstrlenW(appid->DllSurrogate)+1) * sizeof(WCHAR);
|
||||||
sizeof(WCHAR);
|
RegSetValueExW( hkey3, szDLL, 0, REG_SZ,
|
||||||
RegSetValueExW(hkey3,szDLL,0,REG_SZ,
|
(LPBYTE)appid->DllSurrogate, size );
|
||||||
(LPVOID)package->appids[appidIndex].DllSurrogate,size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (package->appids[appidIndex].ActivateAtStorage)
|
if (appid->ActivateAtStorage)
|
||||||
{
|
{
|
||||||
static const WCHAR szActivate[] =
|
static const WCHAR szActivate[] =
|
||||||
{'A','c','t','i','v','a','t','e','A','s',
|
{'A','c','t','i','v','a','t','e','A','s',
|
||||||
'S','t','o','r','a','g','e',0};
|
'S','t','o','r','a','g','e',0};
|
||||||
static const WCHAR szY[] = {'Y',0};
|
static const WCHAR szY[] = {'Y',0};
|
||||||
|
|
||||||
RegSetValueExW(hkey3,szActivate,0,REG_SZ,(LPVOID)szY,4);
|
RegSetValueExW( hkey3, szActivate, 0, REG_SZ,
|
||||||
|
(LPBYTE)szY, sizeof szY );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (package->appids[appidIndex].RunAsInteractiveUser)
|
if (appid->RunAsInteractiveUser)
|
||||||
{
|
{
|
||||||
static const WCHAR szRunAs[] = {'R','u','n','A','s',0};
|
static const WCHAR szRunAs[] = {'R','u','n','A','s',0};
|
||||||
static const WCHAR szUser[] =
|
static const WCHAR szUser[] =
|
||||||
{'I','n','t','e','r','a','c','t','i','v','e',' ',
|
{'I','n','t','e','r','a','c','t','i','v','e',' ',
|
||||||
'U','s','e','r',0};
|
'U','s','e','r',0};
|
||||||
|
|
||||||
RegSetValueExW(hkey3,szRunAs,0,REG_SZ,(LPVOID)szUser,sizeof(szUser));
|
RegSetValueExW( hkey3, szRunAs, 0, REG_SZ,
|
||||||
|
(LPBYTE)szUser, sizeof szUser );
|
||||||
}
|
}
|
||||||
|
|
||||||
RegCloseKey(hkey3);
|
RegCloseKey(hkey3);
|
||||||
|
@ -1017,7 +1004,7 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package)
|
||||||
|
|
||||||
if (argument)
|
if (argument)
|
||||||
{
|
{
|
||||||
RegSetValueExW(hkey3,NULL,0,REG_SZ, (LPVOID)argument, size);
|
RegSetValueExW(hkey3,NULL,0,REG_SZ, (LPBYTE)argument, size);
|
||||||
HeapFree(GetProcessHeap(),0,argument);
|
HeapFree(GetProcessHeap(),0,argument);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1035,7 +1022,7 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package)
|
||||||
progid = package->classes[i].ProgIDText;
|
progid = package->classes[i].ProgIDText;
|
||||||
|
|
||||||
RegCreateKeyW(hkey2,szProgID,&hkey3);
|
RegCreateKeyW(hkey2,szProgID,&hkey3);
|
||||||
RegSetValueExW(hkey3,NULL,0,REG_SZ,(LPVOID)progid,
|
RegSetValueExW(hkey3,NULL,0,REG_SZ,(LPBYTE)progid,
|
||||||
(strlenW(progid)+1) *sizeof(WCHAR));
|
(strlenW(progid)+1) *sizeof(WCHAR));
|
||||||
RegCloseKey(hkey3);
|
RegCloseKey(hkey3);
|
||||||
|
|
||||||
|
@ -1047,22 +1034,21 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package)
|
||||||
package->classes[i].ProgIDIndex].VersionIndIndex].
|
package->classes[i].ProgIDIndex].VersionIndIndex].
|
||||||
ProgID);
|
ProgID);
|
||||||
RegCreateKeyW(hkey2,szVIProgID,&hkey3);
|
RegCreateKeyW(hkey2,szVIProgID,&hkey3);
|
||||||
RegSetValueExW(hkey3,NULL,0,REG_SZ,(LPVOID)viprogid,
|
RegSetValueExW(hkey3,NULL,0,REG_SZ,(LPBYTE)viprogid,
|
||||||
(strlenW(viprogid)+1) *sizeof(WCHAR));
|
(strlenW(viprogid)+1) *sizeof(WCHAR));
|
||||||
RegCloseKey(hkey3);
|
RegCloseKey(hkey3);
|
||||||
HeapFree(GetProcessHeap(), 0, viprogid);
|
HeapFree(GetProcessHeap(), 0, viprogid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (package->classes[i].AppIDIndex >= 0)
|
if (package->classes[i].AppID)
|
||||||
{
|
{
|
||||||
RegSetValueExW(hkey2,szAppID,0,REG_SZ,
|
MSIAPPID *appid = package->classes[i].AppID;
|
||||||
(LPVOID)package->appids[package->classes[i].AppIDIndex].AppID,
|
|
||||||
(strlenW(package->appids[package->classes[i].AppIDIndex].AppID)+1)
|
|
||||||
*sizeof(WCHAR));
|
|
||||||
|
|
||||||
register_appid(package,package->classes[i].AppIDIndex,
|
RegSetValueExW( hkey2, szAppID, 0, REG_SZ, (LPBYTE)appid->AppID,
|
||||||
package->classes[i].Description);
|
(lstrlenW(appid->AppID)+1)*sizeof(WCHAR) );
|
||||||
|
|
||||||
|
register_appid( appid, package->classes[i].Description );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (package->classes[i].IconPath)
|
if (package->classes[i].IconPath)
|
||||||
|
|
|
@ -534,16 +534,17 @@ void ACTION_free_package_structures( MSIPACKAGE* package)
|
||||||
if (package->mimes && package->loaded_mimes > 0)
|
if (package->mimes && package->loaded_mimes > 0)
|
||||||
HeapFree(GetProcessHeap(),0,package->mimes);
|
HeapFree(GetProcessHeap(),0,package->mimes);
|
||||||
|
|
||||||
for (i = 0; i < package->loaded_appids; i++)
|
LIST_FOR_EACH_SAFE( item, cursor, &package->appids )
|
||||||
{
|
{
|
||||||
HeapFree(GetProcessHeap(),0,package->appids[i].RemoteServerName);
|
MSIAPPID *appid = LIST_ENTRY( item, MSIAPPID, entry );
|
||||||
HeapFree(GetProcessHeap(),0,package->appids[i].LocalServer);
|
|
||||||
HeapFree(GetProcessHeap(),0,package->appids[i].ServiceParameters);
|
|
||||||
HeapFree(GetProcessHeap(),0,package->appids[i].DllSurrogate);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (package->appids && package->loaded_appids > 0)
|
list_remove( &appid->entry );
|
||||||
HeapFree(GetProcessHeap(),0,package->appids);
|
HeapFree( GetProcessHeap(), 0, appid->RemoteServerName );
|
||||||
|
HeapFree( GetProcessHeap(), 0, appid->LocalServer );
|
||||||
|
HeapFree( GetProcessHeap(), 0, appid->ServiceParameters );
|
||||||
|
HeapFree( GetProcessHeap(), 0, appid->DllSurrogate );
|
||||||
|
HeapFree( GetProcessHeap(), 0, appid );
|
||||||
|
}
|
||||||
|
|
||||||
if (package->script)
|
if (package->script)
|
||||||
{
|
{
|
||||||
|
|
|
@ -203,8 +203,7 @@ typedef struct tagMSIPACKAGE
|
||||||
UINT loaded_verbs;
|
UINT loaded_verbs;
|
||||||
struct tagMSIMIME *mimes;
|
struct tagMSIMIME *mimes;
|
||||||
UINT loaded_mimes;
|
UINT loaded_mimes;
|
||||||
struct tagMSIAPPID *appids;
|
struct list appids;
|
||||||
UINT loaded_appids;
|
|
||||||
|
|
||||||
struct tagMSISCRIPT *script;
|
struct tagMSISCRIPT *script;
|
||||||
|
|
||||||
|
|
|
@ -386,6 +386,7 @@ MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db )
|
||||||
package->dialog = NULL;
|
package->dialog = NULL;
|
||||||
package->next_dialog = NULL;
|
package->next_dialog = NULL;
|
||||||
list_init( &package->subscriptions );
|
list_init( &package->subscriptions );
|
||||||
|
list_init( &package->appids );
|
||||||
|
|
||||||
/* OK, here is where we do a slew of things to the database to
|
/* OK, here is where we do a slew of things to the database to
|
||||||
* prep for all that is to come as a package */
|
* prep for all that is to come as a package */
|
||||||
|
|
Loading…
Reference in New Issue