invalid memory access on api call?

Mac OSX specific forum
wy328
User
User
Posts: 18
Joined: Sun Jan 15, 2012 3:08 am

invalid memory access on api call?

Post by wy328 »

I'm learning about adding login item on MACOS LION.
but these code crash with memory access error, within the line "CFPreferencesSetAppValue(CFStringCreateWithCString(0,pkey$,0),newArrayRef,CFStringCreateWithCString(0,plist$,0))"
what should i do with "newArrayRef"? thanks!

Code: Select all

Global plist$ = "loginwindow"
Global pkey$ = "AutoLaunchedApplicationDictionary"
appFileName$ = StringField(ProgramFilename(),1,".app")+".app"

ImportC "/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation"
  CFPreferencesSetAppValue(l1,l2,l3)
  CFPreferencesCopyAppValue(l1,l2)
  CFStringCreateWithCString(l1,s1.s,l2)
  CFStringGetCStringPtr(l1,l2)
  CFStringGetCString(CFStringRef.L, *StringBuffer, BufferSize.L, CFStringEncoding.L)
  CFStringGetTypeID()
  CFPreferencesAppSynchronize(l1) 
  CFGetTypeID(l1)
  CFArrayGetTypeID()
  CFArrayGetCount(CFArrayRef.l)
  CFArrayGetValueAtIndex(CFArrayRef.L, Index.L)
  CFDictionaryGetTypeID()
  CFDictionaryGetValue(CFDictionaryRef.L, *KeyToFind)
  CFDictionaryCreateMutable(l1,l2,l3,l4)
  CFDictionaryAddValue(l1,l2,l3)
  CFArrayCreateMutableCopy(l1,l2,l3)
  CFArrayRemoveValueAtIndex(ArrayRef.l,Index.l)
  CFArrayAppendValue(l1,l2)
  CFRelease(obj.l)
EndImport
Procedure.l AddLoginItem(AppPath$)
  Rtn.l = #False
    ArrayRef = CFPreferencesCopyAppValue(CFStringCreateWithCString(0,pkey$,0),CFStringCreateWithCString(0, plist$,0))
    If ArrayRef
      If CFGetTypeID(ArrayRef) = CFArrayGetTypeID()
          newArrayRef = CFArrayCreateMutableCopy(#Null,0,ArrayRef)
          If newArrayRef
            newDictRef = CFDictionaryCreateMutable(#Null,0,#Null,#Null)
            If newDictRef
              KeyRef1 = CFStringCreateWithCString(0, "Hide", 0)
              KeyRef2 = CFStringCreateWithCString(0, "Path", 0)
              CFDictionaryAddValue(newDictRef,KeyRef1,#False)
              CFDictionaryAddValue(newDictRef,KeyRef2,CFStringCreateWithCString(0,AppPath$,0))
              CFArrayAppendValue(newArrayRef,newDictRef)
              CFPreferencesSetAppValue(CFStringCreateWithCString(0,pkey$,0),newArrayRef,CFStringCreateWithCString(0,plist$,0))
              CFPreferencesAppSynchronize(CFStringCreateWithCString(0,plist$,0))
              Rtn = #True
              i = ItemCount
              CFRelease(newArrayRef)
              CFRelease(newDictRef)
            EndIf 
            CFRelease(ArrayRef)
          EndIf   
      EndIf
    EndIf
  ProcedureReturn Rtn 
EndProcedure

Debug AddLoginItem(appFileName$)
wy328
User
User
Posts: 18
Joined: Sun Jan 15, 2012 3:08 am

Re: invalid memory access on api call?

Post by wy328 »

plz....no one knows?
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: invalid memory access on api call?

Post by wilbert »

I changed some thing on your code.
It doesn't crash but doesn't seem to do anything either :?

Code: Select all

appFileName$ = StringField(ProgramFilename(),1,".app")+".app"

ImportC "/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation"
  
  CFSTR(cStr.p-ascii) As "___CFStringMakeConstantString"
  CFStringCreateWithCString(allocator, cStr.p-ascii, encoding)
  CFDictionaryCreate(allocator, *keys, *values, numValues, *keyCallBacks, *valueCallBacks)
  CFNumberCreate(allocator, type, *value)

  CFPreferencesSetAppValue(l1,l2,l3)
  CFPreferencesCopyAppValue(l1,l2)
  CFStringGetCStringPtr(l1,l2)
  CFStringGetCString(CFStringRef.L, *StringBuffer, BufferSize.L, CFStringEncoding.L)
  CFStringGetTypeID()
  CFPreferencesAppSynchronize(l1) 
  CFGetTypeID(l1)
  CFArrayGetTypeID()
  CFArrayGetCount(CFArrayRef.l)
  CFArrayGetValueAtIndex(CFArrayRef.L, Index.L)
  CFDictionaryGetTypeID()
  CFDictionaryGetValue(CFDictionaryRef.L, *KeyToFind)
  CFDictionaryCreateMutable(l1,l2,l3,l4)
  CFDictionaryAddValue(l1,l2,l3)
  CFArrayCreateMutableCopy(l1,l2,l3)
  CFArrayRemoveValueAtIndex(ArrayRef.l,Index.l)
  CFArrayAppendValue(l1,l2)
  CFRelease(obj.l)
  
EndImport

Procedure AddLoginItem(AppPath$)
  
  Rtn = #False
  ArrayRef = CFPreferencesCopyAppValue(CFSTR("AutoLaunchedApplicationDictionary"), CFSTR("loginwindow"))
  
  If ArrayRef And CFGetTypeID(ArrayRef) = CFArrayGetTypeID()
    
    newArrayRef = CFArrayCreateMutableCopy(#Null, 0, ArrayRef)
    CFRelease(ArrayRef)
    
    If newArrayRef
      
      Dim keys.i(1)
      Dim values.i(1)
      BoolFalse.l = #False
      keys(0) = CFSTR("Path")
      keys(1) = CFSTR("Hide")
      values(0) = CFStringCreateWithCString(#Null, AppPath$, 0)
      values(1) = CFNumberCreate(#Null, 3, @BoolFalse)
      newDictRef = CFDictionaryCreate(#Null, @keys(), @values(), 2, #Null, #Null)
      If newDictRef
        CFArrayAppendValue(newArrayRef, newDictRef)
        CFPreferencesSetAppValue(CFSTR("AutoLaunchedApplicationDictionary"), newArrayRef, CFSTR("loginwindow"))
        CFPreferencesAppSynchronize(CFSTR("loginwindow"))
        CFRelease(newDictRef)
        CFRelease(newArrayRef)
        Rtn = #True
      EndIf 
      CFRelease(values(1))
      CFRelease(values(0))
      
    EndIf   
  EndIf
  
  ProcedureReturn Rtn 
  
EndProcedure

Debug AddLoginItem(appFileName$)
wy328
User
User
Posts: 18
Joined: Sun Jan 15, 2012 3:08 am

Re: invalid memory access on api call?

Post by wy328 »

wilbert wrote:I changed some thing on your code.
It doesn't crash but doesn't seem to do anything either :?

Code: Select all

appFileName$ = StringField(ProgramFilename(),1,".app")+".app"

ImportC "/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation"
  
  CFSTR(cStr.p-ascii) As "___CFStringMakeConstantString"
  CFStringCreateWithCString(allocator, cStr.p-ascii, encoding)
  CFDictionaryCreate(allocator, *keys, *values, numValues, *keyCallBacks, *valueCallBacks)
  CFNumberCreate(allocator, type, *value)

  CFPreferencesSetAppValue(l1,l2,l3)
  CFPreferencesCopyAppValue(l1,l2)
  CFStringGetCStringPtr(l1,l2)
  CFStringGetCString(CFStringRef.L, *StringBuffer, BufferSize.L, CFStringEncoding.L)
  CFStringGetTypeID()
  CFPreferencesAppSynchronize(l1) 
  CFGetTypeID(l1)
  CFArrayGetTypeID()
  CFArrayGetCount(CFArrayRef.l)
  CFArrayGetValueAtIndex(CFArrayRef.L, Index.L)
  CFDictionaryGetTypeID()
  CFDictionaryGetValue(CFDictionaryRef.L, *KeyToFind)
  CFDictionaryCreateMutable(l1,l2,l3,l4)
  CFDictionaryAddValue(l1,l2,l3)
  CFArrayCreateMutableCopy(l1,l2,l3)
  CFArrayRemoveValueAtIndex(ArrayRef.l,Index.l)
  CFArrayAppendValue(l1,l2)
  CFRelease(obj.l)
  
EndImport

Procedure AddLoginItem(AppPath$)
  
  Rtn = #False
  ArrayRef = CFPreferencesCopyAppValue(CFSTR("AutoLaunchedApplicationDictionary"), CFSTR("loginwindow"))
  
  If ArrayRef And CFGetTypeID(ArrayRef) = CFArrayGetTypeID()
    
    newArrayRef = CFArrayCreateMutableCopy(#Null, 0, ArrayRef)
    CFRelease(ArrayRef)
    
    If newArrayRef
      
      Dim keys.i(1)
      Dim values.i(1)
      BoolFalse.l = #False
      keys(0) = CFSTR("Path")
      keys(1) = CFSTR("Hide")
      values(0) = CFStringCreateWithCString(#Null, AppPath$, 0)
      values(1) = CFNumberCreate(#Null, 3, @BoolFalse)
      newDictRef = CFDictionaryCreate(#Null, @keys(), @values(), 2, #Null, #Null)
      If newDictRef
        CFArrayAppendValue(newArrayRef, newDictRef)
        CFPreferencesSetAppValue(CFSTR("AutoLaunchedApplicationDictionary"), newArrayRef, CFSTR("loginwindow"))
        CFPreferencesAppSynchronize(CFSTR("loginwindow"))
        CFRelease(newDictRef)
        CFRelease(newArrayRef)
        Rtn = #True
      EndIf 
      CFRelease(values(1))
      CFRelease(values(0))
      
    EndIf   
  EndIf
  
  ProcedureReturn Rtn 
  
EndProcedure

Debug AddLoginItem(appFileName$)

Code: Select all

Global plist$ = "loginwindow"
Global pkey$ = "AutoLaunchedApplicationDictionary"
appFileName$ = StringField(ProgramFilename(),1,".app")+".app"

ImportC "/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation"
  CFSTR(cStr.p-ascii) As "___CFStringMakeConstantString"
  CFDictionaryCreate(allocator, *keys, *values, numValues, *keyCallBacks, *valueCallBacks)
  CFNumberCreate(allocator, type, *value)
  CFPreferencesSetAppValue(l1,l2,l3)
  CFPreferencesCopyAppValue(l1,l2)
  CFStringGetCStringPtr(l1,l2)
  CFStringGetCString(CFStringRef.L, *StringBuffer, BufferSize.L, CFStringEncoding.L)
  CFStringGetTypeID()
  CFPreferencesAppSynchronize(l1) 
  CFGetTypeID(l1)
  CFArrayGetTypeID()
  CFArrayGetCount(CFArrayRef.l)
  CFArrayGetValueAtIndex(CFArrayRef.L, Index.L)
  CFDictionaryGetTypeID()
  CFDictionaryGetValue(CFDictionaryRef.L, *KeyToFind)
  ;CFDictionaryCreateMutable(l1,l2,l3,l4)
  CFDictionaryAddValue(l1,l2,l3)
  CFArrayCreateMutableCopy(l1,l2,l3)
  CFArrayRemoveValueAtIndex(ArrayRef.l,Index.l)
  CFArrayAppendValue(l1,l2)
  CFRelease(obj.l)
  CFBooleanGetValue(l1)
EndImport

Procedure.S ConvertCFStringIntoString(CFStringRef.l)
  Protected String.s = Space(256)
  CFStringGetCString(CFStringRef, @String, Len(String), 0)
  ProcedureReturn Trim(String)
EndProcedure

Procedure CheckLoginItem(AppPath$)
  Rtn.l = #False
  ArrayRef = CFPreferencesCopyAppValue(CFSTR(pkey$),CFSTR(plist$))
  If ArrayRef
    If CFGetTypeID(ArrayRef) = CFArrayGetTypeID()
      ItemCount = CFArrayGetCount(ArrayRef)
      If ItemCount > 1
        For i = 0 To ItemCount - 1
          DictionaryRef = CFArrayGetValueAtIndex(ArrayRef, i)
          If DictionaryRef
            KeyRef = CFSTR("Path")
            StringRef = CFDictionaryGetValue(DictionaryRef, KeyRef)
            CFRelease(KeyRef)
            If StringRef
              itemFileName$ = ConvertCFStringIntoString(StringRef)
              CFRelease(StringRef) 
              Debug Str(i) + ": " + itemFileName$
              If itemFileName$ = AppPath$
                Rtn = #True
                i = ItemCount
              EndIf  
            EndIf
          EndIf
        Next i 
      EndIf   
    EndIf
    CFRelease(ArrayRef)
  EndIf
  ProcedureReturn Rtn
EndProcedure

Procedure RemoveLoginItem(AppPath$)
  Rtn.l = #False
  ArrayRef = CFPreferencesCopyAppValue(CFSTR(pkey$),CFSTR(plist$))
  If ArrayRef And CFGetTypeID(ArrayRef) = CFArrayGetTypeID()
    ItemCount = CFArrayGetCount(ArrayRef)
    Debug "array: " + Str(CFArrayGetCount(ArrayRef))
    If ItemCount > 1
      For i = 0 To ItemCount - 1
        DictionaryRef = CFArrayGetValueAtIndex(ArrayRef, i)
        If DictionaryRef
          KeyRef = CFSTR("Path")
          StringRef = CFDictionaryGetValue(DictionaryRef, KeyRef)
          CFRelease(KeyRef)
          If StringRef
            itemFileName$ = ConvertCFStringIntoString(StringRef)
            CFRelease(StringRef)
            Debug Str(i) + ": " + itemFileName$
            If itemFileName$ = AppPath$
              newArrayRef = CFArrayCreateMutableCopy(#Null, 0, ArrayRef)
              If newArrayRef
                CFArrayRemoveValueAtIndex(newArrayRef,i)
                Debug "new array: " + Str(CFArrayGetCount(newArrayRef))
                CFPreferencesSetAppValue(CFSTR(pkey$), newArrayRef, CFSTR(plist$))
                CFPreferencesAppSynchronize(CFSTR(plist$)) 
                CFRelease(newArrayRef)
                Rtn = #True
                i = ItemCount
              EndIf
            EndIf  
          EndIf
        EndIf 
      Next i  
    EndIf
    CFRelease(ArrayRef)
  EndIf
  ProcedureReturn Rtn
EndProcedure

Procedure AddLoginItem(AppPath$)
  Rtn = #False
  ArrayRef = CFPreferencesCopyAppValue(CFSTR(pkey$), CFSTR(plist$))
  If ArrayRef And CFGetTypeID(ArrayRef) = CFArrayGetTypeID()
    newArrayRef = CFArrayCreateMutableCopy(#Null, 0, ArrayRef)
    CFRelease(ArrayRef)
    If newArrayRef
      Dim keys.i(1)
      Dim values.i(1)
      BoolFalse.l = #False
      keys(0) = CFSTR("Path")
      keys(1) = CFSTR("Hide")
      values(0) = CFSTR(AppPath$)
      values(1) = CFNumberCreate(#Null, 3, @BoolFalse)
      newDictRef = CFDictionaryCreate(#Null, @keys(), @values(), 2, #Null, #Null)
      If newDictRef
        CFArrayAppendValue(newArrayRef, newDictRef)
        CFPreferencesSetAppValue(CFSTR(pkey$), newArrayRef, CFSTR(plist$))
        CFPreferencesAppSynchronize(CFSTR(plist$))
        CFRelease(newDictRef)
        CFRelease(newArrayRef)
        Rtn = #True
      EndIf
      CFRelease(values(1))
      CFRelease(values(0))
    EndIf
  EndIf
  ProcedureReturn Rtn
EndProcedure

Debug AddLoginItem(appFileName$)
Debug CheckLoginItem(appFileName$)
;Debug RemoveLoginItem(appFileName$)
thanks wilbert, you're my hero.
AddLoginItem & CheckLoginItem are working now, but RemoveLoginItem still with error of "invalid memory access".
and what's more, as the document says loginwindow.plist format must be:

Code: Select all

		<dict>
			<key>Hide</key>
			<false/>
			<key>Path</key>
			<string>/tmp/PureBasic1.app</string>
		</dict>
but now it's:

Code: Select all

		<dict>
			<key>Hide</key>
			<integer>0</integer>
			<key>Path</key>
			<string>/tmp/PureBasic1.app</string>
		</dict>
i'm confused... it's hard for me...just post all the code for some one can fix it. :?
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: invalid memory access on api call?

Post by wilbert »

Can you tell me where to find the file that contains everything ?
When I look at /Library/Preferences/loginwindow.plist it seems empty all the time.
wy328
User
User
Posts: 18
Joined: Sun Jan 15, 2012 3:08 am

Re: invalid memory access on api call?

Post by wy328 »

wilbert wrote:Can you tell me where to find the file that contains everything ?
When I look at /Library/Preferences/loginwindow.plist it seems empty all the time.
check the following path:
"/Users/Your Name/Library/Preferences/loginwindow.plist"
please notice that the Library folder is hiden in your home folder.
waitting for your good news. :D
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: invalid memory access on api call?

Post by wilbert »

I didn't look at your Remove procedure yet but the procedure to add should be working now

Code: Select all

#plist = "loginwindow"
#pkey = "AutoLaunchedApplicationDictionary"

appFileName$ = StringField(ProgramFilename(),1,".app")+".app"


; *** code to get kCFBooleanTrue and kCFBooleanFalse ***

Global.l kCFBooleanTrue, kCFBooleanFalse
!mov eax, dword [kCFBooleanTruePtr]
!mov edx, dword [kCFBooleanFalsePtr]
!mov eax, [eax]
!mov edx, [edx]
!mov [v_kCFBooleanTrue], eax
!mov [v_kCFBooleanFalse], edx
DataSection
!extern _kCFBooleanTrue
!extern _kCFBooleanFalse
!kCFBooleanTruePtr: dd _kCFBooleanTrue
!kCFBooleanFalsePtr: dd _kCFBooleanFalse
EndDataSection

; *** end of code to get kCFBooleanTrue and kCFBooleanFalse ***


ImportC "/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation"
  
  CFSTR(cStr.p-ascii) As "___CFStringMakeConstantString"
  CFStringCreateWithCString(allocator, cStr.p-ascii, encoding)
  CFDictionaryCreate(allocator, *keys, *values, numValues, *keyCallBacks, *valueCallBacks)
  CFNumberCreate(allocator, type, *value)
  
  CFPreferencesSetAppValue(l1,l2,l3)
  CFPreferencesCopyAppValue(l1,l2)
  CFStringGetCStringPtr(l1,l2)
  CFStringGetCString(CFStringRef.L, *StringBuffer, BufferSize.L, CFStringEncoding.L)
  CFStringGetTypeID()
  CFPreferencesAppSynchronize(l1) 
  CFGetTypeID(l1)
  CFArrayGetTypeID()
  CFArrayGetCount(CFArrayRef.l)
  CFArrayGetValueAtIndex(CFArrayRef.L, Index.L)
  CFDictionaryGetTypeID()
  CFDictionaryGetValue(CFDictionaryRef.L, *KeyToFind)
  ;CFDictionaryCreateMutable(l1,l2,l3,l4)
  CFDictionaryAddValue(l1,l2,l3)
  CFArrayCreateMutableCopy(l1,l2,l3)
  CFArrayRemoveValueAtIndex(ArrayRef.l,Index.l)
  CFArrayAppendValue(l1,l2)
  CFRelease(obj.l)
  CFBooleanGetValue(l1)
EndImport

Procedure.S ConvertCFStringIntoString(CFStringRef.l)
  Protected String.s = Space(256)
  CFStringGetCString(CFStringRef, @String, Len(String), 0)
  ProcedureReturn Trim(String)
EndProcedure

Procedure CheckLoginItem(AppPath$)
  Rtn.l = #False
  ArrayRef = CFPreferencesCopyAppValue(CFSTR(#pkey),CFSTR(#plist))
  If ArrayRef
    If CFGetTypeID(ArrayRef) = CFArrayGetTypeID()
      ItemCount = CFArrayGetCount(ArrayRef)
      If ItemCount > 1
        For i = 0 To ItemCount - 1
          DictionaryRef = CFArrayGetValueAtIndex(ArrayRef, i)
          If DictionaryRef
            KeyRef = CFSTR("Path")
            StringRef = CFDictionaryGetValue(DictionaryRef, KeyRef)
            CFRelease(KeyRef)
            If StringRef
              itemFileName$ = ConvertCFStringIntoString(StringRef)
              CFRelease(StringRef) 
              Debug Str(i) + ": " + itemFileName$
              If itemFileName$ = AppPath$
                Rtn = #True
                i = ItemCount
              EndIf  
            EndIf
          EndIf
        Next i 
      EndIf   
    EndIf
    CFRelease(ArrayRef)
  EndIf
  ProcedureReturn Rtn
EndProcedure

Procedure RemoveLoginItem(AppPath$)
  Rtn.l = #False
  ArrayRef = CFPreferencesCopyAppValue(CFSTR(#pkey),CFSTR(#plist))
  If ArrayRef And CFGetTypeID(ArrayRef) = CFArrayGetTypeID()
    ItemCount = CFArrayGetCount(ArrayRef)
    Debug "array: " + Str(CFArrayGetCount(ArrayRef))
    If ItemCount > 1
      For i = 0 To ItemCount - 1
        DictionaryRef = CFArrayGetValueAtIndex(ArrayRef, i)
        If DictionaryRef
          KeyRef = CFSTR("Path")
          StringRef = CFDictionaryGetValue(DictionaryRef, KeyRef)
          CFRelease(KeyRef)
          If StringRef
            itemFileName$ = ConvertCFStringIntoString(StringRef)
            CFRelease(StringRef)
            Debug Str(i) + ": " + itemFileName$
            If itemFileName$ = AppPath$
              newArrayRef = CFArrayCreateMutableCopy(#Null, 0, ArrayRef)
              If newArrayRef
                CFArrayRemoveValueAtIndex(newArrayRef,i)
                Debug "new array: " + Str(CFArrayGetCount(newArrayRef))
                CFPreferencesSetAppValue(CFSTR(#pkey), newArrayRef, CFSTR(#plist))
                CFPreferencesAppSynchronize(CFSTR(#plist)) 
                CFRelease(newArrayRef)
                Rtn = #True
                i = ItemCount
              EndIf
            EndIf  
          EndIf
        EndIf 
      Next i  
    EndIf
    CFRelease(ArrayRef)
  EndIf
  ProcedureReturn Rtn
EndProcedure

Procedure AddLoginItem(AppPath$)
  Rtn = #False
  ArrayRef = CFPreferencesCopyAppValue(CFSTR(#pkey), CFSTR(#plist))
  If ArrayRef And CFGetTypeID(ArrayRef) = CFArrayGetTypeID()
    newArrayRef = CFArrayCreateMutableCopy(#Null, 0, ArrayRef)
    CFRelease(ArrayRef)
    If newArrayRef
      Dim keys.i(1)
      Dim values.i(1)
      keys(0) = CFSTR("Path")
      keys(1) = CFSTR("Hide")
      values(0) = CFStringCreateWithCString(#Null, AppPath$, 0)
      values(1) = kCFBooleanFalse
      newDictRef = CFDictionaryCreate(#Null, @keys(), @values(), 2, #Null, #Null)
      If newDictRef
        CFArrayAppendValue(newArrayRef, newDictRef)
        CFPreferencesSetAppValue(CFSTR(#pkey), newArrayRef, CFSTR(#plist))
        CFPreferencesAppSynchronize(CFSTR(#plist))
        CFRelease(newDictRef)
        CFRelease(newArrayRef)
        Rtn = #True
      EndIf
      CFRelease(values(0))
    EndIf
  EndIf
  ProcedureReturn Rtn
EndProcedure

Debug AddLoginItem(appFileName$)
Debug CheckLoginItem(appFileName$)
;Debug RemoveLoginItem(appFileName$)
A little remark, CFSTR is for string constants only.
wy328
User
User
Posts: 18
Joined: Sun Jan 15, 2012 3:08 am

Re: invalid memory access on api call?

Post by wy328 »

wilbert wrote:I didn't look at your Remove procedure yet but the procedure to add should be working now

Code: Select all

#plist = "loginwindow"
#pkey = "AutoLaunchedApplicationDictionary"

appFileName$ = StringField(ProgramFilename(),1,".app")+".app"


; *** code to get kCFBooleanTrue and kCFBooleanFalse ***

Global.l kCFBooleanTrue, kCFBooleanFalse
!mov eax, dword [kCFBooleanTruePtr]
!mov edx, dword [kCFBooleanFalsePtr]
!mov eax, [eax]
!mov edx, [edx]
!mov [v_kCFBooleanTrue], eax
!mov [v_kCFBooleanFalse], edx
DataSection
!extern _kCFBooleanTrue
!extern _kCFBooleanFalse
!kCFBooleanTruePtr: dd _kCFBooleanTrue
!kCFBooleanFalsePtr: dd _kCFBooleanFalse
EndDataSection

; *** end of code to get kCFBooleanTrue and kCFBooleanFalse ***


ImportC "/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation"
  
  CFSTR(cStr.p-ascii) As "___CFStringMakeConstantString"
  CFStringCreateWithCString(allocator, cStr.p-ascii, encoding)
  CFDictionaryCreate(allocator, *keys, *values, numValues, *keyCallBacks, *valueCallBacks)
  CFNumberCreate(allocator, type, *value)
  
  CFPreferencesSetAppValue(l1,l2,l3)
  CFPreferencesCopyAppValue(l1,l2)
  CFStringGetCStringPtr(l1,l2)
  CFStringGetCString(CFStringRef.L, *StringBuffer, BufferSize.L, CFStringEncoding.L)
  CFStringGetTypeID()
  CFPreferencesAppSynchronize(l1) 
  CFGetTypeID(l1)
  CFArrayGetTypeID()
  CFArrayGetCount(CFArrayRef.l)
  CFArrayGetValueAtIndex(CFArrayRef.L, Index.L)
  CFDictionaryGetTypeID()
  CFDictionaryGetValue(CFDictionaryRef.L, *KeyToFind)
  ;CFDictionaryCreateMutable(l1,l2,l3,l4)
  CFDictionaryAddValue(l1,l2,l3)
  CFArrayCreateMutableCopy(l1,l2,l3)
  CFArrayRemoveValueAtIndex(ArrayRef.l,Index.l)
  CFArrayAppendValue(l1,l2)
  CFRelease(obj.l)
  CFBooleanGetValue(l1)
EndImport

Procedure.S ConvertCFStringIntoString(CFStringRef.l)
  Protected String.s = Space(256)
  CFStringGetCString(CFStringRef, @String, Len(String), 0)
  ProcedureReturn Trim(String)
EndProcedure

Procedure CheckLoginItem(AppPath$)
  Rtn.l = #False
  ArrayRef = CFPreferencesCopyAppValue(CFSTR(#pkey),CFSTR(#plist))
  If ArrayRef
    If CFGetTypeID(ArrayRef) = CFArrayGetTypeID()
      ItemCount = CFArrayGetCount(ArrayRef)
      If ItemCount > 1
        For i = 0 To ItemCount - 1
          DictionaryRef = CFArrayGetValueAtIndex(ArrayRef, i)
          If DictionaryRef
            KeyRef = CFSTR("Path")
            StringRef = CFDictionaryGetValue(DictionaryRef, KeyRef)
            CFRelease(KeyRef)
            If StringRef
              itemFileName$ = ConvertCFStringIntoString(StringRef)
              CFRelease(StringRef) 
              Debug Str(i) + ": " + itemFileName$
              If itemFileName$ = AppPath$
                Rtn = #True
                i = ItemCount
              EndIf  
            EndIf
          EndIf
        Next i 
      EndIf   
    EndIf
    CFRelease(ArrayRef)
  EndIf
  ProcedureReturn Rtn
EndProcedure

Procedure RemoveLoginItem(AppPath$)
  Rtn.l = #False
  ArrayRef = CFPreferencesCopyAppValue(CFSTR(#pkey),CFSTR(#plist))
  If ArrayRef And CFGetTypeID(ArrayRef) = CFArrayGetTypeID()
    ItemCount = CFArrayGetCount(ArrayRef)
    Debug "array: " + Str(CFArrayGetCount(ArrayRef))
    If ItemCount > 1
      For i = 0 To ItemCount - 1
        DictionaryRef = CFArrayGetValueAtIndex(ArrayRef, i)
        If DictionaryRef
          KeyRef = CFSTR("Path")
          StringRef = CFDictionaryGetValue(DictionaryRef, KeyRef)
          CFRelease(KeyRef)
          If StringRef
            itemFileName$ = ConvertCFStringIntoString(StringRef)
            CFRelease(StringRef)
            Debug Str(i) + ": " + itemFileName$
            If itemFileName$ = AppPath$
              newArrayRef = CFArrayCreateMutableCopy(#Null, 0, ArrayRef)
              If newArrayRef
                CFArrayRemoveValueAtIndex(newArrayRef,i)
                Debug "new array: " + Str(CFArrayGetCount(newArrayRef))
                CFPreferencesSetAppValue(CFSTR(#pkey), newArrayRef, CFSTR(#plist))
                CFPreferencesAppSynchronize(CFSTR(#plist)) 
                CFRelease(newArrayRef)
                Rtn = #True
                i = ItemCount
              EndIf
            EndIf  
          EndIf
        EndIf 
      Next i  
    EndIf
    CFRelease(ArrayRef)
  EndIf
  ProcedureReturn Rtn
EndProcedure

Procedure AddLoginItem(AppPath$)
  Rtn = #False
  ArrayRef = CFPreferencesCopyAppValue(CFSTR(#pkey), CFSTR(#plist))
  If ArrayRef And CFGetTypeID(ArrayRef) = CFArrayGetTypeID()
    newArrayRef = CFArrayCreateMutableCopy(#Null, 0, ArrayRef)
    CFRelease(ArrayRef)
    If newArrayRef
      Dim keys.i(1)
      Dim values.i(1)
      keys(0) = CFSTR("Path")
      keys(1) = CFSTR("Hide")
      values(0) = CFStringCreateWithCString(#Null, AppPath$, 0)
      values(1) = kCFBooleanFalse
      newDictRef = CFDictionaryCreate(#Null, @keys(), @values(), 2, #Null, #Null)
      If newDictRef
        CFArrayAppendValue(newArrayRef, newDictRef)
        CFPreferencesSetAppValue(CFSTR(#pkey), newArrayRef, CFSTR(#plist))
        CFPreferencesAppSynchronize(CFSTR(#plist))
        CFRelease(newDictRef)
        CFRelease(newArrayRef)
        Rtn = #True
      EndIf
      CFRelease(values(0))
    EndIf
  EndIf
  ProcedureReturn Rtn
EndProcedure

Debug AddLoginItem(appFileName$)
Debug CheckLoginItem(appFileName$)
;Debug RemoveLoginItem(appFileName$)
A little remark, CFSTR is for string constants only.
cool.i have to study hard.:D
wy328
User
User
Posts: 18
Joined: Sun Jan 15, 2012 3:08 am

Re: invalid memory access on api call?

Post by wy328 »

Post Reply